[gcr] gcr: Add support for viewing certificate requests
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gcr] gcr: Add support for viewing certificate requests
- Date: Thu, 24 Nov 2011 06:57:47 +0000 (UTC)
commit b189cedc1a41703dedd3e9a256e7689c34e38705
Author: Stef Walter <stefw collabora co uk>
Date: Tue Nov 8 09:32:32 2011 +0100
gcr: Add support for viewing certificate requests
* Both PKCS#10/CSR and SPKAC
* Update mime database for SPKAC and CSR
* Associate viewer with these files
https://bugzilla.gnome.org/show_bug.cgi?id=663604
egg/pkix.asn | 5 +
gcr/Makefile.am | 3 +
gcr/gcr-certificate-renderer-private.h | 51 +++
gcr/gcr-certificate-renderer.c | 392 ++++++++++++-----------
gcr/gcr-certificate-req-renderer.c | 550 +++++++++++++++++++++++++++++++
gcr/gcr-certificate-req-renderer.h | 70 ++++
gcr/gcr-certificate.c | 100 +------
gcr/gcr-crypto-types.xml | 16 +
gcr/gcr-key-size.c | 106 ++++++
gcr/gcr-key-size.h | 33 ++
gcr/gcr-oids.list | 1 +
gcr/gcr-renderer.c | 2 +
gcr/gcr-types.h | 2 +-
gcr/gcr-viewer.desktop.in | 2 +-
gcr/gcr-viewer.desktop.in.in | 2 +-
gcr/tests/Makefile.am | 1 +
gcr/tests/files/pem-with-attributes.req | 64 ++++
gcr/tests/frob-request.c | 96 ++++++
po/POTFILES.in | 1 +
19 files changed, 1217 insertions(+), 280 deletions(-)
---
diff --git a/egg/pkix.asn b/egg/pkix.asn
index 6cf966b..02c2732 100644
--- a/egg/pkix.asn
+++ b/egg/pkix.asn
@@ -1240,4 +1240,9 @@ SignedPublicKeyAndChallenge ::= SEQUENCE {
signature BIT STRING
}
+-- pkcs-9 extension requests: added by gnome-keyring
+-- http://mirror.switch.ch/ftp/doc/standard/pkcs/pkcs-9/pkcs-9.txt
+
+ExtensionRequest ::= SEQUENCE OF Extension
+
END
diff --git a/gcr/Makefile.am b/gcr/Makefile.am
index ebb4cc8..2045125 100644
--- a/gcr/Makefile.am
+++ b/gcr/Makefile.am
@@ -113,6 +113,7 @@ libgcr_base_ GCR_MAJOR@_la_SOURCES = \
gcr-importer.c gcr-importer.h \
gcr-import-interaction.c gcr-import-interaction.h \
gcr-internal.h \
+ gcr-key-size.c gcr-key-size.h \
gcr-library.c gcr-library.h \
gcr-memory.c \
gcr-memory-icon.c gcr-memory-icon.h \
@@ -138,6 +139,7 @@ libgcr_ GCR_MAJOR@_la_SOURCES = \
gcr-certificate-exporter.c gcr-certificate-exporter.h \
gcr-certificate-extensions.c gcr-certificate-extensions.h \
gcr-certificate-renderer.c gcr-certificate-renderer.h \
+ gcr-certificate-req-renderer.c gcr-certificate-req-renderer.h \
gcr-certificate-widget.c gcr-certificate-widget.h \
gcr-collection-model.c gcr-collection-model.h \
gcr-combo-selector.c gcr-combo-selector.h \
@@ -150,6 +152,7 @@ libgcr_ GCR_MAJOR@_la_SOURCES = \
gcr-gnupg-records.c gcr-gnupg-records.h \
gcr-import-button.c gcr-import-button.h \
gcr-key-renderer.c gcr-key-renderer.h \
+ gcr-key-size.c gcr-key-size.h \
gcr-key-widget.c gcr-key-widget.h \
gcr-list-selector.c gcr-list-selector.h gcr-list-selector-private.h \
gcr-live-search.c gcr-live-search.h \
diff --git a/gcr/gcr-certificate-renderer-private.h b/gcr/gcr-certificate-renderer-private.h
new file mode 100644
index 0000000..f7dadbf
--- /dev/null
+++ b/gcr/gcr-certificate-renderer-private.h
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+#if !defined (__GCR_INSIDE_HEADER__) && !defined (GCR_COMPILATION)
+#error "Only <gcr/gcr.h> or <gcr/gcr-base.h> can be included directly."
+#endif
+
+#ifndef __GCR_CERTIFICATE_RENDERER_PRIVATE_H__
+#define __GCR_CERTIFICATE_RENDERER_PRIVATE_H__
+
+#include "gcr-display-view.h"
+#include "gcr-renderer.h"
+
+G_BEGIN_DECLS
+
+void _gcr_certificate_renderer_append_distinguished_name (GcrRenderer *renderer,
+ GcrDisplayView *view,
+ GNode *dn);
+
+void _gcr_certificate_renderer_append_subject_public_key (GcrRenderer *renderer,
+ GcrDisplayView *view,
+ guint key_size,
+ GNode *subject_public_key);
+
+void _gcr_certificate_renderer_append_signature (GcrRenderer *renderer,
+ GcrDisplayView *view,
+ GNode *asn);
+
+void _gcr_certificate_renderer_append_extension (GcrRenderer *renderer,
+ GcrDisplayView *view,
+ GNode *asn);
+
+G_END_DECLS
+
+#endif /* __GCR_CERTIFICATE_RENDERER_PRIVATE_H__ */
diff --git a/gcr/gcr-certificate-renderer.c b/gcr/gcr-certificate-renderer.c
index ebceda3..ae3f73c 100644
--- a/gcr/gcr-certificate-renderer.c
+++ b/gcr/gcr-certificate-renderer.c
@@ -23,6 +23,7 @@
#include "gcr-certificate-exporter.h"
#include "gcr-certificate-extensions.h"
#include "gcr-certificate-renderer.h"
+#include "gcr-certificate-renderer-private.h"
#include "gcr-display-view.h"
#include "gcr-fingerprint.h"
#include "gcr-icons.h"
@@ -102,11 +103,10 @@ calculate_label (GcrCertificateRenderer *self)
}
static gboolean
-append_extension_basic_constraints (GcrCertificateRenderer *self,
+append_extension_basic_constraints (GcrRenderer *renderer,
GcrDisplayView *view,
EggBytes *data)
{
- GcrRenderer *renderer = GCR_RENDERER (self);
gboolean is_ca = FALSE;
gint path_len = -1;
gchar *number;
@@ -128,11 +128,10 @@ append_extension_basic_constraints (GcrCertificateRenderer *self,
}
static gboolean
-append_extension_extended_key_usage (GcrCertificateRenderer *self,
+append_extension_extended_key_usage (GcrRenderer *renderer,
GcrDisplayView *view,
EggBytes *data)
{
- GcrRenderer *renderer = GCR_RENDERER (self);
GQuark *oids;
GString *text;
guint i;
@@ -161,11 +160,10 @@ append_extension_extended_key_usage (GcrCertificateRenderer *self,
}
static gboolean
-append_extension_subject_key_identifier (GcrCertificateRenderer *self,
+append_extension_subject_key_identifier (GcrRenderer *renderer,
GcrDisplayView *view,
EggBytes *data)
{
- GcrRenderer *renderer = GCR_RENDERER (self);
gpointer keyid;
gsize n_keyid;
@@ -194,11 +192,10 @@ static const struct {
};
static gboolean
-append_extension_key_usage (GcrCertificateRenderer *self,
+append_extension_key_usage (GcrRenderer *renderer,
GcrDisplayView *view,
EggBytes *data)
{
- GcrRenderer *renderer = GCR_RENDERER (self);
gulong key_usage;
GString *text;
guint i;
@@ -225,11 +222,10 @@ append_extension_key_usage (GcrCertificateRenderer *self,
}
static gboolean
-append_extension_subject_alt_name (GcrCertificateRenderer *self,
+append_extension_subject_alt_name (GcrRenderer *renderer,
GcrDisplayView *view,
EggBytes *data)
{
- GcrRenderer *renderer = GCR_RENDERER (self);
GArray *general_names;
GcrGeneralName *general;
guint i;
@@ -256,12 +252,13 @@ append_extension_subject_alt_name (GcrCertificateRenderer *self,
return TRUE;
}
-
static gboolean
-append_extension_hex (GcrCertificateRenderer *self, GcrDisplayView *view,
- GQuark oid, gconstpointer data, gsize n_data)
+append_extension_hex (GcrRenderer *renderer,
+ GcrDisplayView *view,
+ GQuark oid,
+ gconstpointer data,
+ gsize n_data)
{
- GcrRenderer *renderer = GCR_RENDERER (self);
const gchar *text;
_gcr_display_view_append_heading (view, renderer, _("Extension"));
@@ -275,107 +272,6 @@ append_extension_hex (GcrCertificateRenderer *self, GcrDisplayView *view,
}
static gboolean
-append_extension (GcrCertificateRenderer *self,
- GcrDisplayView *view,
- GNode *asn,
- gint index)
-{
- GcrRenderer *renderer = GCR_RENDERER (self);
- GNode *node;
- GQuark oid;
- EggBytes *value;
- gboolean critical;
- gboolean ret = FALSE;
-
- /* Make sure it is present */
- node = egg_asn1x_node (asn, "tbsCertificate", "extensions", index, NULL);
- if (node == NULL)
- return FALSE;
-
- /* Dig out the OID */
- oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (node, "extnID", NULL));
- g_return_val_if_fail (oid, FALSE);
-
- /* Extension value */
- value = egg_asn1x_get_raw_value (egg_asn1x_node (node, "extnValue", NULL));
-
- /* The custom parsers */
- if (oid == GCR_OID_BASIC_CONSTRAINTS)
- ret = append_extension_basic_constraints (self, view, value);
- else if (oid == GCR_OID_EXTENDED_KEY_USAGE)
- ret = append_extension_extended_key_usage (self, view, value);
- else if (oid == GCR_OID_SUBJECT_KEY_IDENTIFIER)
- ret = append_extension_subject_key_identifier (self, view, value);
- else if (oid == GCR_OID_KEY_USAGE)
- ret = append_extension_key_usage (self, view, value);
- else if (oid == GCR_OID_SUBJECT_ALT_NAME)
- ret = append_extension_subject_alt_name (self, view, value);
-
- /* Otherwise the default raw display */
- if (ret == FALSE)
- ret = append_extension_hex (self, view, oid,
- egg_bytes_get_data (value),
- egg_bytes_get_size (value));
-
- /* Critical */
- if (ret == TRUE && egg_asn1x_get_boolean (egg_asn1x_node (node, "critical", NULL), &critical)) {
- _gcr_display_view_append_value (view, renderer, _("Critical"),
- critical ? _("Yes") : _("No"), FALSE);
- }
-
- egg_bytes_unref (value);
- return ret;
-}
-
-typedef struct _on_parsed_dn_args {
- GcrCertificateRenderer *renderer;
- GcrDisplayView *view;
-} on_parsed_dn_args;
-
-static void
-on_parsed_dn_part (guint index,
- GQuark oid,
- EggBytes *value,
- gpointer user_data)
-{
- GcrCertificateRenderer *self = ((on_parsed_dn_args*)user_data)->renderer;
- GcrDisplayView *view = ((on_parsed_dn_args*)user_data)->view;
- const gchar *attr;
- const gchar *desc;
- gchar *field = NULL;
- gchar *display;
-
- g_return_if_fail (GCR_IS_CERTIFICATE_RENDERER (self));
-
- attr = egg_oid_get_name (oid);
- desc = egg_oid_get_description (oid);
-
- /* Combine them into something sane */
- if (attr && desc) {
- if (strcmp (attr, desc) == 0)
- field = g_strdup (attr);
- else
- field = g_strdup_printf ("%s (%s)", attr, desc);
- } else if (!attr && !desc) {
- field = g_strdup ("");
- } else if (attr) {
- field = g_strdup (attr);
- } else if (desc) {
- field = g_strdup (desc);
- } else {
- g_assert_not_reached ();
- }
-
- display = egg_dn_print_value (oid, value);
- if (display == NULL)
- display = g_strdup ("");
-
- _gcr_display_view_append_value (view, GCR_RENDERER (self), field, display, FALSE);
- g_free (field);
- g_free (display);
-}
-
-static gboolean
on_delete_unref_dialog (GtkWidget *widget, GdkEvent *event, gpointer data)
{
g_object_unref (widget);
@@ -574,21 +470,17 @@ static void
gcr_certificate_renderer_render (GcrRenderer *renderer, GcrViewer *viewer)
{
GcrCertificateRenderer *self;
+ GNode *extension;
gconstpointer data;
- gsize n_data, n_raw;
+ gsize n_data;
GcrDisplayView *view;
- on_parsed_dn_args args;
- const gchar *text;
GcrCertificate *cert;
- gpointer raw;
EggBytes *number;
gulong version;
guint bits, index;
gchar *display;
EggBytes *bytes;
- EggBytes *value;
GNode *asn;
- GQuark oid;
GDate date;
GIcon *icon;
@@ -643,16 +535,15 @@ gcr_certificate_renderer_render (GcrRenderer *renderer, GcrViewer *viewer)
_gcr_display_view_start_details (view, renderer);
- args.renderer = self;
- args.view = view;
-
/* The subject */
_gcr_display_view_append_heading (view, renderer, _("Subject Name"));
- egg_dn_parse (egg_asn1x_node (asn, "tbsCertificate", "subject", "rdnSequence", NULL), on_parsed_dn_part, &args);
+ _gcr_certificate_renderer_append_distinguished_name (renderer, view,
+ egg_asn1x_node (asn, "tbsCertificate", "subject", "rdnSequence", NULL));
/* The Issuer */
_gcr_display_view_append_heading (view, renderer, _("Issuer Name"));
- egg_dn_parse (egg_asn1x_node (asn, "tbsCertificate", "issuer", "rdnSequence", NULL), on_parsed_dn_part, &args);
+ _gcr_certificate_renderer_append_distinguished_name (renderer, view,
+ egg_asn1x_node (asn, "tbsCertificate", "issuer", "rdnSequence", NULL));
/* The Issued Parameters */
_gcr_display_view_append_heading (view, renderer, _("Issued Certificate"));
@@ -689,73 +580,25 @@ gcr_certificate_renderer_render (GcrRenderer *renderer, GcrViewer *viewer)
_gcr_display_view_append_fingerprint (view, renderer, data, n_data, "SHA1", G_CHECKSUM_SHA1);
_gcr_display_view_append_fingerprint (view, renderer, data, n_data, "MD5", G_CHECKSUM_MD5);
- /* Signature */
- _gcr_display_view_append_heading (view, renderer, _("Signature"));
-
- 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 (view, renderer, _("Signature Algorithm"), text, FALSE);
-
- value = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "signatureAlgorithm", "parameters", NULL));
- if (value) {
- _gcr_display_view_append_hex (view, renderer, _("Signature Parameters"),
- egg_bytes_get_data (value),
- egg_bytes_get_size (value));
- egg_bytes_unref (value);
- }
-
- value = egg_asn1x_get_bits_as_raw (egg_asn1x_node (asn, "signature", NULL), &bits);
- g_return_if_fail (value != NULL);
- _gcr_display_view_append_hex (view, renderer, _("Signature"),
- egg_bytes_get_data (value), bits / 8);
- egg_bytes_unref (value);
-
/* Public Key Info */
_gcr_display_view_append_heading (view, renderer, _("Public Key Info"));
-
- 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 (view, renderer, _("Key Algorithm"), text, FALSE);
-
- value = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "tbsCertificate", "subjectPublicKeyInfo",
- "algorithm", "parameters", NULL));
- if (value) {
- _gcr_display_view_append_hex (view, renderer, _("Key Parameters"),
- egg_bytes_get_data (value),
- egg_bytes_get_size (value));
- egg_bytes_unref (value);
- }
-
bits = gcr_certificate_get_key_size (cert);
- if (bits > 0) {
- display = g_strdup_printf ("%u", bits);
- _gcr_display_view_append_value (view, renderer, _("Key Size"), display, FALSE);
- g_free (display);
- }
-
- value = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "tbsCertificate",
- "subjectPublicKeyInfo", NULL));
- raw = gcr_fingerprint_from_subject_public_key_info (egg_bytes_get_data (value),
- egg_bytes_get_size (value),
- G_CHECKSUM_SHA1, &n_raw);
- _gcr_display_view_append_hex (view, renderer, _("Key SHA1 Fingerprint"), raw, n_raw);
- egg_bytes_unref (value);
- g_free (raw);
-
- value = egg_asn1x_get_bits_as_raw (egg_asn1x_node (asn, "tbsCertificate", "subjectPublicKeyInfo",
- "subjectPublicKey", NULL), &bits);
- g_return_if_fail (value != NULL);
- _gcr_display_view_append_hex (view, renderer, _("Public Key"),
- egg_bytes_get_data (value), bits / 8);
- egg_bytes_unref (value);
+ _gcr_certificate_renderer_append_subject_public_key (renderer, view, bits,
+ egg_asn1x_node (asn, "tbsCertificate",
+ "subjectPublicKeyInfo", NULL));
/* Extensions */
for (index = 1; TRUE; ++index) {
- if (!append_extension (self, view, asn, index))
+ extension = egg_asn1x_node (asn, "tbsCertificate", "extensions", index, NULL);
+ if (extension == NULL)
break;
+ _gcr_certificate_renderer_append_extension (renderer, view, extension);
}
+ /* Signature */
+ _gcr_display_view_append_heading (view, renderer, _("Signature"));
+ _gcr_certificate_renderer_append_signature (renderer, view, asn);
+
egg_asn1x_destroy (asn);
_gcr_display_view_end (view, renderer);
}
@@ -939,3 +782,184 @@ gcr_certificate_renderer_set_attributes (GcrCertificateRenderer *self, GckAttrib
g_object_notify (G_OBJECT (self), "attributes");
}
+
+typedef struct {
+ GcrRenderer *renderer;
+ GcrDisplayView *view;
+} AppendDnClosure;
+
+static void
+on_parsed_dn_part (guint index,
+ GQuark oid,
+ EggBytes *value,
+ gpointer user_data)
+{
+ GcrRenderer *renderer = ((AppendDnClosure *)user_data)->renderer;
+ GcrDisplayView *view = ((AppendDnClosure *)user_data)->view;
+ const gchar *attr;
+ const gchar *desc;
+ gchar *field = NULL;
+ gchar *display;
+
+ attr = egg_oid_get_name (oid);
+ desc = egg_oid_get_description (oid);
+
+ /* Combine them into something sane */
+ if (attr && desc) {
+ if (strcmp (attr, desc) == 0)
+ field = g_strdup (attr);
+ else
+ field = g_strdup_printf ("%s (%s)", attr, desc);
+ } else if (!attr && !desc) {
+ field = g_strdup ("");
+ } else if (attr) {
+ field = g_strdup (attr);
+ } else if (desc) {
+ field = g_strdup (desc);
+ } else {
+ g_assert_not_reached ();
+ }
+
+ display = egg_dn_print_value (oid, value);
+ if (display == NULL)
+ display = g_strdup ("");
+
+ _gcr_display_view_append_value (view, renderer, field, display, FALSE);
+ g_free (field);
+ g_free (display);
+}
+
+
+void
+_gcr_certificate_renderer_append_distinguished_name (GcrRenderer *renderer,
+ GcrDisplayView *view,
+ GNode *dn)
+{
+ AppendDnClosure closure;
+
+ g_return_if_fail (GCR_IS_RENDERER (renderer));
+ g_return_if_fail (GCR_IS_DISPLAY_VIEW (view));
+ g_return_if_fail (dn != NULL);
+
+ closure.renderer = renderer;
+ closure.view = view;
+ egg_dn_parse (dn, on_parsed_dn_part, &closure);
+}
+
+void
+_gcr_certificate_renderer_append_subject_public_key (GcrRenderer *renderer,
+ GcrDisplayView *view,
+ guint key_nbits,
+ GNode *subject_public_key)
+{
+ const gchar *text;
+ gchar *display;
+ EggBytes *value;
+ guchar *raw;
+ gsize n_raw;
+ GQuark oid;
+ guint bits;
+
+ oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (subject_public_key,
+ "algorithm", "algorithm", NULL));
+ text = egg_oid_get_description (oid);
+ _gcr_display_view_append_value (view, renderer, _("Key Algorithm"), text, FALSE);
+
+ value = egg_asn1x_get_raw_element (egg_asn1x_node (subject_public_key,
+ "algorithm", "parameters", NULL));
+ if (value) {
+ _gcr_display_view_append_hex (view, renderer, _("Key Parameters"),
+ egg_bytes_get_data (value),
+ egg_bytes_get_size (value));
+ egg_bytes_unref (value);
+ }
+
+ if (key_nbits > 0) {
+ display = g_strdup_printf ("%u", key_nbits);
+ _gcr_display_view_append_value (view, renderer, _("Key Size"), display, FALSE);
+ g_free (display);
+ }
+
+ value = egg_asn1x_get_raw_element (subject_public_key);
+ raw = gcr_fingerprint_from_subject_public_key_info (egg_bytes_get_data (value),
+ egg_bytes_get_size (value),
+ G_CHECKSUM_SHA1, &n_raw);
+ _gcr_display_view_append_hex (view, renderer, _("Key SHA1 Fingerprint"), raw, n_raw);
+ egg_bytes_unref (value);
+ g_free (raw);
+
+ value = egg_asn1x_get_bits_as_raw (egg_asn1x_node (subject_public_key, "subjectPublicKey", NULL), &bits);
+ _gcr_display_view_append_hex (view, renderer, _("Public Key"),
+ egg_bytes_get_data (value), bits / 8);
+ egg_bytes_unref (value);
+}
+
+void
+_gcr_certificate_renderer_append_signature (GcrRenderer *renderer,
+ GcrDisplayView *view,
+ GNode *asn)
+{
+ const gchar *text;
+ EggBytes *value;
+ GQuark oid;
+ guint bits;
+
+ 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 (view, renderer, _("Signature Algorithm"), text, FALSE);
+
+ value = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "signatureAlgorithm", "parameters", NULL));
+ if (value) {
+ _gcr_display_view_append_hex (view, renderer, _("Signature Parameters"),
+ egg_bytes_get_data (value),
+ egg_bytes_get_size (value));
+ egg_bytes_unref (value);
+ }
+
+ value = egg_asn1x_get_bits_as_raw (egg_asn1x_node (asn, "signature", NULL), &bits);
+ _gcr_display_view_append_hex (view, renderer, _("Signature"),
+ egg_bytes_get_data (value), bits / 8);
+ egg_bytes_unref (value);
+}
+
+void
+_gcr_certificate_renderer_append_extension (GcrRenderer *renderer,
+ GcrDisplayView *view,
+ GNode *node)
+{
+ GQuark oid;
+ EggBytes *value;
+ gboolean critical;
+ gboolean ret = FALSE;
+
+ /* Dig out the OID */
+ oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (node, "extnID", NULL));
+ g_return_if_fail (oid);
+
+ /* Extension value */
+ value = egg_asn1x_get_raw_value (egg_asn1x_node (node, "extnValue", NULL));
+
+ /* The custom parsers */
+ if (oid == GCR_OID_BASIC_CONSTRAINTS)
+ ret = append_extension_basic_constraints (renderer, view, value);
+ else if (oid == GCR_OID_EXTENDED_KEY_USAGE)
+ ret = append_extension_extended_key_usage (renderer, view, value);
+ else if (oid == GCR_OID_SUBJECT_KEY_IDENTIFIER)
+ ret = append_extension_subject_key_identifier (renderer, view, value);
+ else if (oid == GCR_OID_KEY_USAGE)
+ ret = append_extension_key_usage (renderer, view, value);
+ else if (oid == GCR_OID_SUBJECT_ALT_NAME)
+ ret = append_extension_subject_alt_name (renderer, view, value);
+
+ /* Otherwise the default raw display */
+ if (ret == FALSE)
+ ret = append_extension_hex (renderer, view, oid,
+ egg_bytes_get_data (value),
+ egg_bytes_get_size (value));
+
+ /* Critical */
+ if (ret == TRUE && egg_asn1x_get_boolean (egg_asn1x_node (node, "critical", NULL), &critical)) {
+ _gcr_display_view_append_value (view, renderer, _("Critical"),
+ critical ? _("Yes") : _("No"), FALSE);
+ }
+}
diff --git a/gcr/gcr-certificate-req-renderer.c b/gcr/gcr-certificate-req-renderer.c
new file mode 100644
index 0000000..78ebad6
--- /dev/null
+++ b/gcr/gcr-certificate-req-renderer.c
@@ -0,0 +1,550 @@
+/*
+ * 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-certificate-renderer-private.h"
+#include "gcr-certificate-req-renderer.h"
+#include "gcr-display-view.h"
+#include "gcr-key-size.h"
+#include "gcr-oids.h"
+
+#if 0
+#include "gcr-certificate.h"
+#include "gcr-certificate-exporter.h"
+#include "gcr-certificate-extensions.h"
+#include "gcr-certificate-renderer.h"
+#include "gcr-fingerprint.h"
+#include "gcr-icons.h"
+#include "gcr-oids.h"
+#include "gcr-simple-certificate.h"
+#include "gcr-renderer.h"
+#endif
+
+#include "egg/egg-asn1x.h"
+#include "egg/egg-asn1-defs.h"
+#include "egg/egg-dn.h"
+#include "egg/egg-oid.h"
+
+#include "gck/gck.h"
+
+#include <glib/gi18n-lib.h>
+
+/**
+ * GcrCertificateReqRenderer:
+ *
+ * An implementation of #GcrRenderer which renders certificate requests
+ */
+
+/**
+ * GcrCertificateReqRendererClass:
+ * @parent_class: The parent class
+ *
+ * The class for #GcrCertificateReqRenderer
+ */
+
+enum {
+ PROP_0,
+ PROP_LABEL,
+ PROP_ATTRIBUTES
+};
+
+struct _GcrCertificateReqRendererPrivate {
+ GckAttributes *attrs;
+ gchar *label;
+
+ guint key_size;
+ gulong type;
+ GNode *asn;
+};
+
+static void _gcr_certificate_req_renderer_iface (GcrRendererIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GcrCertificateReqRenderer, _gcr_certificate_req_renderer, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (GCR_TYPE_RENDERER, _gcr_certificate_req_renderer_iface);
+);
+
+static gchar*
+calculate_label (GcrCertificateReqRenderer *self)
+{
+ gchar *label = NULL;
+
+ if (self->pv->label)
+ return g_strdup (self->pv->label);
+
+ if (self->pv->attrs) {
+ if (gck_attributes_find_string (self->pv->attrs, CKA_LABEL, &label))
+ return label;
+ }
+
+ if (self->pv->asn && self->pv->type == CKQ_GCR_PKCS10) {
+ label = egg_dn_read_part (egg_asn1x_node (self->pv->asn,
+ "certificationRequestInfo",
+ "subject",
+ "rdnSequence",
+ NULL), "CN");
+ }
+
+ if (label != NULL)
+ return label;
+
+ return g_strdup (_("Certificate request"));
+}
+
+static void
+_gcr_certificate_req_renderer_init (GcrCertificateReqRenderer *self)
+{
+ self->pv = (G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_CERTIFICATE_REQ_RENDERER,
+ GcrCertificateReqRendererPrivate));
+}
+
+static void
+_gcr_certificate_req_renderer_finalize (GObject *obj)
+{
+ GcrCertificateReqRenderer *self = GCR_CERTIFICATE_REQ_RENDERER (obj);
+
+ if (self->pv->attrs)
+ gck_attributes_unref (self->pv->attrs);
+ self->pv->attrs = NULL;
+
+ g_free (self->pv->label);
+ self->pv->label = NULL;
+
+ egg_asn1x_destroy (self->pv->asn);
+
+ G_OBJECT_CLASS (_gcr_certificate_req_renderer_parent_class)->finalize (obj);
+}
+
+static void
+_gcr_certificate_req_renderer_set_property (GObject *obj,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GcrCertificateReqRenderer *self = GCR_CERTIFICATE_REQ_RENDERER (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");
+ gcr_renderer_emit_data_changed (GCR_RENDERER (self));
+ break;
+ case PROP_ATTRIBUTES:
+ _gcr_certificate_req_renderer_set_attributes (self, g_value_get_boxed (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+_gcr_certificate_req_renderer_get_property (GObject *obj,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GcrCertificateReqRenderer *self = GCR_CERTIFICATE_REQ_RENDERER (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->attrs);
+ break;
+ default:
+ gcr_certificate_mixin_get_property (obj, prop_id, value, pspec);
+ break;
+ }
+}
+
+static void
+_gcr_certificate_req_renderer_class_init (GcrCertificateReqRendererClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GckAttributes *registered;
+
+ _gcr_oids_init ();
+
+ g_type_class_add_private (klass, sizeof (GcrCertificateReqRendererPrivate));
+
+ gobject_class->finalize = _gcr_certificate_req_renderer_finalize;
+ gobject_class->set_property = _gcr_certificate_req_renderer_set_property;
+ gobject_class->get_property = _gcr_certificate_req_renderer_get_property;
+
+ /**
+ * GcrCertificateReqRenderer:attributes:
+ *
+ * The certificate attributes to display. One of the attributes must be
+ * a CKA_VALUE type attribute which contains a DER encoded certificate.
+ */
+ g_object_class_install_property (gobject_class, PROP_ATTRIBUTES,
+ g_param_spec_boxed ("attributes", "Attributes", "Certificate pkcs11 attributes",
+ GCK_TYPE_ATTRIBUTES, G_PARAM_READWRITE));
+
+ /**
+ * GcrCertificateReqRenderer:label:
+ *
+ * The label to display.
+ */
+ g_object_class_install_property (gobject_class, PROP_LABEL,
+ g_param_spec_string ("label", "Label", "Certificate Label",
+ "", G_PARAM_READWRITE));
+
+ /* Register this as a renderer which can be loaded */
+ registered = gck_attributes_new ();
+ gck_attributes_add_ulong (registered, CKA_CLASS, CKO_GCR_CERTIFICATE_REQUEST);
+ gck_attributes_add_ulong (registered, CKA_GCR_CERTIFICATE_REQUEST_TYPE, CKQ_GCR_PKCS10);
+ gcr_renderer_register (GCR_TYPE_CERTIFICATE_REQ_RENDERER, registered);
+ gck_attributes_unref (registered);
+
+ registered = gck_attributes_new ();
+ gck_attributes_add_ulong (registered, CKA_CLASS, CKO_GCR_CERTIFICATE_REQUEST);
+ gck_attributes_add_ulong (registered, CKA_GCR_CERTIFICATE_REQUEST_TYPE, CKQ_GCR_SPKAC);
+ gcr_renderer_register (GCR_TYPE_CERTIFICATE_REQ_RENDERER, registered);
+ gck_attributes_unref (registered);
+}
+
+static gboolean
+append_extension_request (GcrRenderer *renderer,
+ GcrDisplayView *view,
+ GNode *attribute)
+{
+ EggBytes *value;
+ GNode *node;
+ GNode *asn;
+ guint i;
+
+ node = egg_asn1x_node (attribute, "values", 1, NULL);
+ if (node == NULL)
+ return FALSE;
+
+ value = egg_asn1x_get_raw_element (node);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "ExtensionRequest", value);
+ if (asn == NULL)
+ return FALSE;
+
+ for (i = 1; TRUE; i++) {
+ node = egg_asn1x_node (asn, i, NULL);
+ if (node == NULL)
+ break;
+ _gcr_certificate_renderer_append_extension (renderer, view, node);
+ }
+
+ egg_asn1x_destroy (asn);
+ return TRUE;
+}
+
+static void
+append_attribute (GcrRenderer *renderer,
+ GcrDisplayView *view,
+ GNode *attribute)
+{
+ GQuark oid;
+ EggBytes *value;
+ const gchar *text;
+ GNode *node;
+ gboolean ret = FALSE;
+ gint i;
+
+ /* Dig out the OID */
+ oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (attribute, "type", NULL));
+ g_return_if_fail (oid);
+
+ if (oid == GCR_OID_PKCS9_ATTRIBUTE_EXTENSION_REQ)
+ ret = append_extension_request (renderer, view, attribute);
+
+ if (!ret) {
+ _gcr_display_view_append_heading (view, renderer, _("Attribute"));
+
+ /* Extension type */
+ text = egg_oid_get_description (oid);
+ _gcr_display_view_append_value (view, renderer, _("Type"), text, FALSE);
+
+ for (i = 1; TRUE; i++) {
+ node = egg_asn1x_node (attribute, "values", i, NULL);
+ if (node == NULL)
+ break;
+ value = egg_asn1x_get_raw_element (node);
+ _gcr_display_view_append_hex (view, renderer, _("Value"),
+ egg_bytes_get_data (value),
+ egg_bytes_get_size (value));
+ egg_bytes_unref (value);
+ }
+ }
+}
+
+static guint
+ensure_key_size (GcrCertificateReqRenderer *self,
+ GNode *public_key)
+{
+ if (self->pv->key_size)
+ return self->pv->key_size;
+
+ self->pv->key_size = _gcr_key_size_calculate (public_key);
+ return self->pv->key_size;
+}
+
+static void
+render_pkcs10_certificate_req (GcrCertificateReqRenderer *self,
+ GcrDisplayView *view)
+{
+ GcrRenderer *renderer = GCR_RENDERER (self);
+ GNode *public_key;
+ GNode *attribute;
+ GNode *subject;
+ gchar *display;
+ gulong version;
+ guint bits;
+ guint i;
+
+ display = calculate_label (self);
+ _gcr_display_view_append_title (view, renderer, display);
+ g_free (display);
+
+ _gcr_display_view_append_content (view, renderer, _("Certificate request"), NULL);
+
+ subject = egg_asn1x_node (self->pv->asn, "certificationRequestInfo",
+ "subject", "rdnSequence", NULL);
+ display = egg_dn_read_part (subject, "CN");
+ _gcr_display_view_append_content (view, renderer, _("Identity"), display);
+ g_free (display);
+
+ _gcr_display_view_start_details (view, renderer);
+
+ /* The subject */
+ _gcr_display_view_append_heading (view, renderer, _("Subject Name"));
+ _gcr_certificate_renderer_append_distinguished_name (renderer, view, subject);
+
+ /* The certificate request type */
+ _gcr_display_view_append_heading (view, renderer, _("Certificate request"));
+ _gcr_display_view_append_value (view, renderer, _("Type"), "PKCS#10", FALSE);
+ if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (self->pv->asn,
+ "certificationRequestInfo",
+ "version", NULL), &version))
+ g_return_if_reached ();
+ display = g_strdup_printf ("%lu", version + 1);
+ _gcr_display_view_append_value (view, renderer, _("Version"), display, FALSE);
+ g_free (display);
+
+ _gcr_display_view_append_heading (view, renderer, _("Public Key Info"));
+ public_key = egg_asn1x_node (self->pv->asn, "certificationRequestInfo", "subjectPKInfo", NULL);
+ bits = ensure_key_size (self, public_key);
+ _gcr_certificate_renderer_append_subject_public_key (renderer, view,
+ bits, public_key);
+
+ /* Attributes */
+ for (i = 1; TRUE; ++i) {
+ /* Make sure it is present */
+ attribute = egg_asn1x_node (self->pv->asn, "certificationRequestInfo", "attributes", i, NULL);
+ if (attribute == NULL)
+ break;
+ append_attribute (renderer, view, attribute);
+ }
+
+ /* Signature */
+ _gcr_display_view_append_heading (view, renderer, _("Signature"));
+ _gcr_certificate_renderer_append_signature (renderer, view, self->pv->asn);
+}
+
+static void
+render_spkac_certificate_req (GcrCertificateReqRenderer *self,
+ GcrDisplayView *view)
+{
+ GcrRenderer *renderer = GCR_RENDERER (self);
+ GNode *public_key;
+ gchar *display;
+ guint bits;
+
+ display = calculate_label (self);
+ _gcr_display_view_append_title (view, renderer, display);
+ g_free (display);
+
+ _gcr_display_view_append_content (view, renderer, _("Certificate request"), NULL);
+
+ _gcr_display_view_start_details (view, renderer);
+
+ /* The certificate request type */
+ _gcr_display_view_append_heading (view, renderer, _("Certificate request"));
+ _gcr_display_view_append_value (view, renderer, _("Type"), "SPKAC", FALSE);
+
+ display = egg_asn1x_get_string_as_utf8 (egg_asn1x_node (self->pv->asn, "publicKeyAndChallenge",
+ "challenge", NULL), NULL);
+ _gcr_display_view_append_value (view, renderer, _("Challenge"), display, FALSE);
+ g_free (display);
+
+ _gcr_display_view_append_heading (view, renderer, _("Public Key Info"));
+ public_key = egg_asn1x_node (self->pv->asn, "publicKeyAndChallenge", "spki", NULL);
+ bits = ensure_key_size (self, public_key);
+ _gcr_certificate_renderer_append_subject_public_key (renderer, view,
+ bits, public_key);
+
+ /* Signature */
+ _gcr_display_view_append_heading (view, renderer, _("Signature"));
+ _gcr_certificate_renderer_append_signature (renderer, view, self->pv->asn);
+}
+
+static void
+gcr_certificate_req_renderer_render (GcrRenderer *renderer,
+ GcrViewer *viewer)
+{
+ GcrCertificateReqRenderer *self;
+ GcrDisplayView *view;
+ GIcon *icon;
+
+ self = GCR_CERTIFICATE_REQ_RENDERER (renderer);
+
+ if (GCR_IS_DISPLAY_VIEW (viewer)) {
+ view = GCR_DISPLAY_VIEW (viewer);
+
+ } else {
+ g_warning ("GcrCertificateReqRenderer only works with internal specific "
+ "GcrViewer returned by gcr_viewer_new().");
+ return;
+ }
+
+ _gcr_display_view_begin (view, renderer);
+
+ icon = g_themed_icon_new ("dialog-question");
+ _gcr_display_view_set_icon (view, GCR_RENDERER (self), icon);
+ g_object_unref (icon);
+
+ switch (self->pv->type) {
+ case CKQ_GCR_PKCS10:
+ render_pkcs10_certificate_req (self, view);
+ break;
+ case CKQ_GCR_SPKAC:
+ render_spkac_certificate_req (self, view);
+ break;
+ default:
+ g_warning ("unknown request type in GcrCertificateReqRenderer");
+ break;
+ }
+
+ _gcr_display_view_end (view, renderer);
+}
+
+static void
+_gcr_certificate_req_renderer_iface (GcrRendererIface *iface)
+{
+ iface->render_view = gcr_certificate_req_renderer_render;
+}
+
+/**
+ * gcr_certificate_req_renderer_new_for_attributes:
+ * @label: (allow-none): the label to display
+ * @attrs: the attributes to display
+ *
+ * Create a new certificate request renderer to display the label and attributes.
+ * One of the attributes should be a CKA_VALUE type attribute containing a DER
+ * encoded PKCS\#10 certificate request or an SPKAC request.
+ *
+ * Returns: (transfer full): a newly allocated #GcrCertificateReqRenderer, which
+ * should be released with g_object_unref()
+ */
+GcrRenderer *
+_gcr_certificate_req_renderer_new_for_attributes (const gchar *label,
+ GckAttributes *attrs)
+{
+ return g_object_new (GCR_TYPE_CERTIFICATE_REQ_RENDERER,
+ "label", label,
+ "attributes", attrs,
+ NULL);
+}
+
+/**
+ * gcr_certificate_req_renderer_get_attributes:
+ * @self: the renderer
+ *
+ * Get the PKCS\#11 attributes, if any, set for this renderer to display.
+ *
+ * Returns: (allow-none) (transfer none): the attributes, owned by the renderer
+ */
+GckAttributes *
+_gcr_certificate_req_renderer_get_attributes (GcrCertificateReqRenderer *self)
+{
+ g_return_val_if_fail (GCR_IS_CERTIFICATE_REQ_RENDERER (self), NULL);
+ return self->pv->attrs;
+}
+
+/**
+ * gcr_certificate_req_renderer_set_attributes:
+ * @self: the renderer
+ * @attrs: (allow-none): attributes to set
+ *
+ * Set the PKCS\#11 attributes for this renderer to display. One of the attributes
+ * should be a CKA_VALUE type attribute containing a DER encoded PKCS\#10
+ * certificate request or an SPKAC request.
+ */
+void
+_gcr_certificate_req_renderer_set_attributes (GcrCertificateReqRenderer *self,
+ GckAttributes *attrs)
+{
+ GckAttribute *value;
+ GNode *asn = NULL;
+ gulong type = 0;
+ EggBytes *bytes;
+
+ g_return_if_fail (GCR_IS_CERTIFICATE_REQ_RENDERER (self));
+
+ if (attrs) {
+ value = gck_attributes_find (attrs, CKA_VALUE);
+ if (value == NULL) {
+ g_warning ("no CKA_VALUE found in attributes passed to "
+ "GcrCertificateReqRenderer attributes property");
+ return;
+ }
+
+ bytes = egg_bytes_new_with_free_func (value->value, value->length,
+ gck_attributes_unref, gck_attributes_ref (attrs));
+
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-10-CertificationRequest", bytes);
+ if (asn != NULL) {
+ type = CKQ_GCR_PKCS10;
+ } else {
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "SignedPublicKeyAndChallenge", bytes);
+ if (asn != NULL) {
+ type = CKQ_GCR_SPKAC;
+ } else {
+ g_warning ("the data contained in the CKA_VALUE attribute passed to "
+ "GcrCertificateReqRenderer was not valid DER encoded PKCS#10 "
+ "or SPKAC");
+ }
+ }
+
+ egg_bytes_unref (bytes);
+
+ if (type == 0)
+ return;
+
+ gck_attributes_ref (attrs);
+ }
+
+ if (self->pv->attrs)
+ gck_attributes_unref (self->pv->attrs);
+ self->pv->attrs = attrs;
+ self->pv->asn = asn;
+ self->pv->type = type;
+ self->pv->key_size = 0; /* calculated later */
+
+ gcr_renderer_emit_data_changed (GCR_RENDERER (self));
+ g_object_notify (G_OBJECT (self), "attributes");
+}
diff --git a/gcr/gcr-certificate-req-renderer.h b/gcr/gcr-certificate-req-renderer.h
new file mode 100644
index 0000000..856f925
--- /dev/null
+++ b/gcr/gcr-certificate-req-renderer.h
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+#if !defined (__GCR_INSIDE_HEADER__) && !defined (GCR_COMPILATION)
+#error "Only <gcr/gcr.h> or <gcr/gcr-base.h> can be included directly."
+#endif
+
+#ifndef __GCR_CERTIFICATE_REQ_RENDERER_H__
+#define __GCR_CERTIFICATE_REQ_RENDERER_H__
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+#include "gcr-certificate.h"
+#include "gcr-renderer.h"
+#include "gcr-types.h"
+
+G_BEGIN_DECLS
+
+#define GCR_TYPE_CERTIFICATE_REQ_RENDERER (_gcr_certificate_req_renderer_get_type ())
+#define GCR_CERTIFICATE_REQ_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_CERTIFICATE_REQ_RENDERER, GcrCertificateReqRenderer))
+#define GCR_CERTIFICATE_REQ_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_CERTIFICATE_REQ_RENDERER, GcrCertificateReqRendererClass))
+#define GCR_IS_CERTIFICATE_REQ_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_CERTIFICATE_REQ_RENDERER))
+#define GCR_IS_CERTIFICATE_REQ_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_CERTIFICATE_REQ_RENDERER))
+#define GCR_CERTIFICATE_REQ_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_CERTIFICATE_REQ_RENDERER, GcrCertificateReqRendererClass))
+
+typedef struct _GcrCertificateReqRenderer GcrCertificateReqRenderer;
+typedef struct _GcrCertificateReqRendererClass GcrCertificateReqRendererClass;
+typedef struct _GcrCertificateReqRendererPrivate GcrCertificateReqRendererPrivate;
+
+struct _GcrCertificateReqRenderer {
+ GObject parent;
+
+ /*< private >*/
+ GcrCertificateReqRendererPrivate *pv;
+};
+
+struct _GcrCertificateReqRendererClass {
+ GObjectClass parent_class;
+};
+
+GType _gcr_certificate_req_renderer_get_type (void);
+
+GcrRenderer * _gcr_certificate_req_renderer_new_for_attributes (const gchar *label,
+ struct _GckAttributes *attrs);
+
+GckAttributes * _gcr_certificate_req_renderer_get_attributes (GcrCertificateReqRenderer *self);
+
+void _gcr_certificate_req_renderer_set_attributes (GcrCertificateReqRenderer *self,
+ GckAttributes *attrs);
+
+G_END_DECLS
+
+#endif /* __GCR_CERTIFICATE_REQ_RENDERER_H__ */
diff --git a/gcr/gcr-certificate.c b/gcr/gcr-certificate.c
index 889c67a..75860b5 100644
--- a/gcr/gcr-certificate.c
+++ b/gcr/gcr-certificate.c
@@ -25,6 +25,7 @@
#include "gcr-comparable.h"
#include "gcr-icons.h"
#include "gcr-internal.h"
+#include "gcr-key-size.h"
#include "gcr-oids.h"
#include "egg/egg-asn1x.h"
@@ -177,97 +178,6 @@ certificate_info_load (GcrCertificate *cert)
return info;
}
-static guint
-calculate_rsa_key_size (EggBytes *data)
-{
- EggBytes *content;
- guint key_size;
- GNode *asn;
-
- asn = egg_asn1x_create_and_decode (pk_asn1_tab, "RSAPublicKey", data);
- g_return_val_if_fail (asn != NULL, 0);
-
- content = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "modulus", NULL));
- if (!content)
- g_return_val_if_reached (0);
-
- egg_asn1x_destroy (asn);
-
- /* Removes the complement */
- key_size = (egg_bytes_get_size (content) / 2) * 2 * 8;
-
- egg_bytes_unref (content);
- return key_size;
-}
-
-static guint
-calculate_dsa_params_size (EggBytes *data)
-{
- EggBytes *content;
- gsize params_size;
- GNode *asn;
-
- asn = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAParameters", data);
- g_return_val_if_fail (asn != NULL, 0);
-
- content = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "p", NULL));
- if (!content)
- g_return_val_if_reached (0);
-
- egg_asn1x_destroy (asn);
-
- /* Removes the complement */
- params_size = (egg_bytes_get_size (content) / 2) * 2 * 8;
-
- egg_bytes_unref (content);
- return params_size;
-}
-
-static guint
-calculate_key_size (GcrCertificateInfo *info)
-{
- GNode *asn;
- EggBytes *data;
- guint key_size = 0, n_bits;
- EggBytes *key;
- GQuark oid;
-
- data = egg_asn1x_get_raw_element (egg_asn1x_node (info->asn1, "tbsCertificate", "subjectPublicKeyInfo", NULL));
- g_return_val_if_fail (data != NULL, 0);
-
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "SubjectPublicKeyInfo", data);
- g_return_val_if_fail (asn != NULL, 0);
-
- egg_bytes_unref (data);
-
- /* Figure out the algorithm */
- oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "algorithm", "algorithm", NULL));
- g_return_val_if_fail (oid, 0);
-
- /* RSA keys are stored in the main subjectPublicKey field */
- if (oid == GCR_OID_PKIX1_RSA) {
-
- /* A bit string so we cannot process in place */
- key = egg_asn1x_get_bits_as_raw (egg_asn1x_node (asn, "subjectPublicKey", NULL), &n_bits);
- g_return_val_if_fail (key != NULL, 0);
- key_size = calculate_rsa_key_size (key);
- egg_bytes_unref (key);
-
- /* The DSA key size is discovered by the prime in params */
- } else if (oid == GCR_OID_PKIX1_DSA) {
- key = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "algorithm", "parameters", NULL));
- key_size = calculate_dsa_params_size (key);
- egg_bytes_unref (key);
-
- } else {
- g_message ("unsupported key algorithm in certificate: %s", g_quark_to_string (oid));
- }
-
- egg_asn1x_destroy (asn);
-
- return key_size;
-}
-
static GChecksum*
digest_certificate (GcrCertificate *self, GChecksumType type)
{
@@ -815,14 +725,18 @@ guint
gcr_certificate_get_key_size (GcrCertificate *self)
{
GcrCertificateInfo *info;
+ GNode *subject_public_key;
g_return_val_if_fail (GCR_IS_CERTIFICATE (self), 0);
info = certificate_info_load (self);
g_return_val_if_fail (info, 0);
- if (!info->key_size)
- info->key_size = calculate_key_size (info);
+ if (!info->key_size) {
+ subject_public_key = egg_asn1x_node (info->asn1, "tbsCertificate",
+ "subjectPublicKeyInfo", NULL);
+ info->key_size = _gcr_key_size_calculate (subject_public_key);
+ }
return info->key_size;
}
diff --git a/gcr/gcr-crypto-types.xml b/gcr/gcr-crypto-types.xml
index b911ccd..c92577c 100644
--- a/gcr/gcr-crypto-types.xml
+++ b/gcr/gcr-crypto-types.xml
@@ -127,6 +127,7 @@
<comment>PKCS#10 Certificate Request</comment>
<acronym>PKCS#10</acronym>
<glob pattern="*.p10"/>
+ <glob pattern="*.csr"/>
</mime-type>
<!-- Non standard: OpenSSL PEM format -->
@@ -139,6 +140,21 @@
</magic>
</mime-type>
+ <!-- Non standard: SPKAC DER format -->
+ <mime-type type="application/x-spkac">
+ <comment>SPKAC Certificate Request</comment>
+ <glob pattern="*.spkac"/>
+ </mime-type>
+
+ <!-- Non standard: SPKAC DER format -->
+ <mime-type type="application/x-spkac+base64">
+ <comment>SPKAC Certificate Request in OpenSSL format</comment>
+ <sub-class-of type="text/plain"/>
+ <magic priority="75">
+ <match type="string" value="SPKAC=" offset="0"/>
+ </magic>
+ </mime-type>
+
<!-- Non standard: OpenSSL PEM format -->
<mime-type type="application/x-pem-key">
<comment>Private Key in PEM format</comment>
diff --git a/gcr/gcr-key-size.c b/gcr/gcr-key-size.c
new file mode 100644
index 0000000..06c5c09
--- /dev/null
+++ b/gcr/gcr-key-size.c
@@ -0,0 +1,106 @@
+/*
+ * 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-key-size.h"
+#include "gcr-oids.h"
+
+#include "egg/egg-asn1x.h"
+#include "egg/egg-asn1-defs.h"
+
+static guint
+calculate_rsa_key_size (EggBytes *data)
+{
+ GNode *asn;
+ EggBytes *content;
+ guint key_size;
+
+ asn = egg_asn1x_create_and_decode (pk_asn1_tab, "RSAPublicKey", data);
+ g_return_val_if_fail (asn, 0);
+
+ content = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "modulus", NULL));
+ if (!content)
+ g_return_val_if_reached (0);
+
+ egg_asn1x_destroy (asn);
+
+ /* Removes the complement */
+ key_size = (egg_bytes_get_size (content) / 2) * 2 * 8;
+
+ egg_bytes_unref (content);
+ return key_size;
+}
+
+static guint
+calculate_dsa_params_size (EggBytes *data)
+{
+ GNode *asn;
+ EggBytes *content;
+ guint key_size;
+
+ asn = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAParameters", data);
+ g_return_val_if_fail (asn, 0);
+
+ content = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "p", NULL));
+ if (!content)
+ g_return_val_if_reached (0);
+
+ egg_asn1x_destroy (asn);
+
+ /* Removes the complement */
+ key_size = (egg_bytes_get_size (content) / 2) * 2 * 8;
+
+ egg_bytes_unref (content);
+ return key_size;
+}
+
+guint
+_gcr_key_size_calculate (GNode *subject_public_key)
+{
+ EggBytes *key;
+ guint key_size = 0, n_bits;
+ GQuark oid;
+
+ /* Figure out the algorithm */
+ oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (subject_public_key,
+ "algorithm", "algorithm", NULL));
+ g_return_val_if_fail (oid, 0);
+
+ /* RSA keys are stored in the main subjectPublicKey field */
+ if (oid == GCR_OID_PKIX1_RSA) {
+
+ /* A bit string so we cannot process in place */
+ key = egg_asn1x_get_bits_as_raw (egg_asn1x_node (subject_public_key, "subjectPublicKey", NULL), &n_bits);
+ g_return_val_if_fail (key != NULL, 0);
+ key_size = calculate_rsa_key_size (key);
+ egg_bytes_unref (key);
+
+ /* The DSA key size is discovered by the prime in params */
+ } else if (oid == GCR_OID_PKIX1_DSA) {
+ key = egg_asn1x_get_raw_element (egg_asn1x_node (subject_public_key, "algorithm", "parameters", NULL));
+ key_size = calculate_dsa_params_size (key);
+ egg_bytes_unref (key);
+
+ } else {
+ g_message ("unsupported key algorithm in certificate: %s", g_quark_to_string (oid));
+ }
+
+ return key_size;
+}
diff --git a/gcr/gcr-key-size.h b/gcr/gcr-key-size.h
new file mode 100644
index 0000000..8232cd3
--- /dev/null
+++ b/gcr/gcr-key-size.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * 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.
+ *
+ * Author: Stef Walter <stefw collabora co uk>
+ */
+
+#ifndef __GCR_KEY_SIZE_H__
+#define __GCR_KEY_SIZE_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+guint _gcr_key_size_calculate (GNode *subject_public_key);
+
+G_END_DECLS
+
+#endif /* __GCR_KEY_RENDERER_H__ */
diff --git a/gcr/gcr-oids.list b/gcr/gcr-oids.list
index 552c601..2fe3364 100644
--- a/gcr/gcr-oids.list
+++ b/gcr/gcr-oids.list
@@ -12,6 +12,7 @@ PKCS7_SIGNED_DATA 1.2.840.113549.1.7.2
PKCS7_ENCRYPTED_DATA 1.2.840.113549.1.7.6
PKCS9_ATTRIBUTE_FRIENDLY 1.2.840.113549.1.9.20
PKCS9_ATTRIBUTE_LOCAL_KEY_ID 1.2.840.113549.1.9.21
+PKCS9_ATTRIBUTE_EXTENSION_REQ 1.2.840.113549.1.9.14
PKCS12_BAG_PKCS8_KEY 1.2.840.113549.1.12.10.1.1
PKCS12_BAG_PKCS8_ENCRYPTED_KEY 1.2.840.113549.1.12.10.1.2
PKCS12_BAG_CERTIFICATE 1.2.840.113549.1.12.10.1.3
diff --git a/gcr/gcr-renderer.c b/gcr/gcr-renderer.c
index c98376b..296bcf0 100644
--- a/gcr/gcr-renderer.c
+++ b/gcr/gcr-renderer.c
@@ -25,6 +25,7 @@
#include "gcr-renderer.h"
#include "gcr-certificate-renderer.h"
+#include "gcr-certificate-req-renderer.h"
#include "gcr-gnupg-renderer.h"
#include "gcr-key-renderer.h"
@@ -289,6 +290,7 @@ void
gcr_renderer_register_well_known (void)
{
g_type_class_unref (g_type_class_ref (GCR_TYPE_CERTIFICATE_RENDERER));
+ g_type_class_unref (g_type_class_ref (GCR_TYPE_CERTIFICATE_REQ_RENDERER));
g_type_class_unref (g_type_class_ref (GCR_TYPE_KEY_RENDERER));
g_type_class_unref (g_type_class_ref (GCR_TYPE_GNUPG_RENDERER));
}
diff --git a/gcr/gcr-types.h b/gcr/gcr-types.h
index e43e7ef..dd522be 100644
--- a/gcr/gcr-types.h
+++ b/gcr/gcr-types.h
@@ -120,7 +120,7 @@ enum {
};
enum {
- CKQ_GCR_PKCS10,
+ CKQ_GCR_PKCS10 = 1,
CKQ_GCR_SPKAC
};
diff --git a/gcr/gcr-viewer.desktop.in b/gcr/gcr-viewer.desktop.in
index 4d4a432..3f45c8a 100644
--- a/gcr/gcr-viewer.desktop.in
+++ b/gcr/gcr-viewer.desktop.in
@@ -1,6 +1,6 @@
[Desktop Entry]
Name=View file
-MimeType=application/pkcs12;application/pkcs12+pem;application/pkcs7-mime;application/pkcs7-mime+pem;application/pkcs8;application/pkcs8+pem;application/pkix-cert;application/pkix-cert+pem;application/pkix-crl;application/pkix-crl+pem;application/x-pem-file;application/x-pem-key;application/x-pkcs12;application/x-pkcs7-certificates;application/x-x509-ca-cert;application/x-x509-user-cert;
+MimeType=application/pkcs12;application/pkcs12+pem;application/pkcs7-mime;application/pkcs7-mime+pem;application/pkcs8;application/pkcs8+pem;application/pkix-cert;application/pkix-cert+pem;application/pkix-crl;application/pkix-crl+pem;application/x-pem-file;application/x-pem-key;application/x-pkcs12;application/x-pkcs7-certificates;application/x-x509-ca-cert;application/x-x509-user-cert;application/pkcs10;application/pkcs10+pem;application/x-spkac;application/x-spkac+base64;
Exec=gcr-viewer
Type=Application
Terminal=false
diff --git a/gcr/gcr-viewer.desktop.in.in b/gcr/gcr-viewer.desktop.in.in
index 6cd913a..a9622ac 100644
--- a/gcr/gcr-viewer.desktop.in.in
+++ b/gcr/gcr-viewer.desktop.in.in
@@ -1,6 +1,6 @@
[Desktop Entry]
Name=View file
-MimeType=application/pkcs12;application/pkcs12+pem;application/pkcs7-mime;application/pkcs7-mime+pem;application/pkcs8;application/pkcs8+pem;application/pkix-cert;application/pkix-cert+pem;application/pkix-crl;application/pkix-crl+pem;application/x-pem-file;application/x-pem-key;application/x-pkcs12;application/x-pkcs7-certificates;application/x-x509-ca-cert;application/x-x509-user-cert;
+MimeType=application/pkcs12;application/pkcs12+pem;application/pkcs7-mime;application/pkcs7-mime+pem;application/pkcs8;application/pkcs8+pem;application/pkix-cert;application/pkix-cert+pem;application/pkix-crl;application/pkix-crl+pem;application/x-pem-file;application/x-pem-key;application/x-pkcs12;application/x-pkcs7-certificates;application/x-x509-ca-cert;application/x-x509-user-cert;application/pkcs10;application/pkcs10+pem;application/x-spkac;application/x-spkac+base64;
Exec=gcr-viewer
Type=Application
Terminal=false
diff --git a/gcr/tests/Makefile.am b/gcr/tests/Makefile.am
index 5ac8369..c133c17 100644
--- a/gcr/tests/Makefile.am
+++ b/gcr/tests/Makefile.am
@@ -64,6 +64,7 @@ noinst_PROGRAMS = \
frob-tree-selector \
frob-openpgp \
frob-parser \
+ frob-request \
frob-unlock \
frob-unlock-options
diff --git a/gcr/tests/files/pem-with-attributes.req b/gcr/tests/files/pem-with-attributes.req
new file mode 100644
index 0000000..bcbe8f5
--- /dev/null
+++ b/gcr/tests/files/pem-with-attributes.req
@@ -0,0 +1,64 @@
+Certificate Request:
+ Data:
+ Version: 0 (0x0)
+ Subject: CN=test.example.com
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:c9:45:f5:a6:a6:f6:d1:96:1a:4d:1b:2b:18:a7:
+ ba:69:4e:90:3b:64:9d:14:71:9a:38:0d:fe:66:89:
+ cd:c6:34:05:c0:c9:2a:02:22:5f:3e:c9:10:c2:df:
+ e8:c8:a5:d9:78:20:6a:81:ad:80:b0:16:a2:d1:6b:
+ e9:ed:2f:95:69:c2:52:2b:db:76:48:00:c9:56:44:
+ fa:a7:f4:64:a6:7b:08:58:14:b6:2d:3c:c3:6a:80:
+ 3e:25:48:a8:52:2a:a0:ff:fc:4a:5e:01:05:f8:c3:
+ 58:db:26:58:8f:42:85:f0:7a:e8:8d:cd:28:a8:c7:
+ 24:cd:65:6d:26:86:88:f0:8b:ab:a2:58:8b:fc:91:
+ 45:66:49:03:79:44:f3:d9:d6:0b:49:6c:e6:d2:25:
+ 83:0c:1e:1f:61:e4:b8:53:ab:c7:8a:58:a6:c1:ce:
+ a4:04:b4:3f:36:48:d5:02:50:85:b3:2c:4c:af:f7:
+ 88:85:be:f1:cf:32:db:cd:52:23:90:71:2b:ad:04:
+ be:18:be:7d:67:4d:0b:bc:d6:92:82:ae:a4:27:98:
+ f1:72:cc:16:f2:5d:f3:78:fa:76:0d:c5:13:88:a5:
+ 87:02:3e:41:a2:a2:36:b9:90:07:4f:53:b9:9c:17:
+ 05:65:9b:da:6d:f4:62:ab:3d:05:7a:8a:fe:e3:c3:
+ 1e:31
+ Exponent: 65537 (0x10001)
+ Attributes:
+ Requested Extensions:
+ X509v3 Subject Alternative Name:
+ DNS:test.example.com, DNS:other.example.com
+ Signature Algorithm: sha1WithRSAEncryption
+ b9:97:4a:53:7e:0f:14:46:ae:d7:6f:fc:1a:33:b1:40:c7:ae:
+ 64:06:c8:2d:b5:5a:a0:e8:bf:8e:af:92:e1:7d:ad:3c:6b:c0:
+ c6:d2:cb:c4:98:e7:2c:fa:d6:d5:ee:77:dc:5e:99:9d:33:23:
+ d0:f7:61:30:ef:86:00:b3:08:4a:24:ce:5a:86:8d:91:95:84:
+ bc:4b:16:33:46:1e:92:3f:7a:fb:f0:f2:27:c3:07:e3:b0:b6:
+ 1c:a4:88:ef:69:69:9f:16:fd:4c:79:46:63:f9:84:8a:a7:16:
+ 8d:80:ee:a5:a8:54:a2:a4:0b:4b:0b:a7:38:a3:e9:d5:14:0f:
+ 0c:1a:5d:25:93:fa:6e:29:95:71:30:90:ca:15:a2:41:2d:e0:
+ 97:0b:36:b2:4c:36:66:16:24:3d:26:c0:26:6a:c8:10:57:ca:
+ 79:b1:b7:ae:e4:95:38:b9:75:66:09:3b:40:31:87:7f:6d:73:
+ 1f:ee:18:b3:de:c8:9c:11:78:00:eb:56:63:5d:f8:a3:58:aa:
+ 44:d1:94:50:46:ff:19:77:7e:85:f8:7c:ba:a4:b9:25:3c:8a:
+ ba:19:c1:10:bc:b6:43:af:ad:60:76:2d:cd:5d:ef:86:4a:1d:
+ b0:0a:91:8a:20:98:cd:c8:9e:43:d5:7c:9c:a9:e2:8b:f3:86:
+ fe:a4:00:1a
+-----BEGIN CERTIFICATE REQUEST-----
+MIICoTCCAYkCAQAwGzEZMBcGA1UEAxMQdGVzdC5leGFtcGxlLmNvbTCCASIwDQYJ
+KoZIhvcNAQEBBQADggEPADCCAQoCggEBAMlF9aam9tGWGk0bKxinumlOkDtknRRx
+mjgN/maJzcY0BcDJKgIiXz7JEMLf6Mil2XggaoGtgLAWotFr6e0vlWnCUivbdkgA
+yVZE+qf0ZKZ7CFgUti08w2qAPiVIqFIqoP/8Sl4BBfjDWNsmWI9ChfB66I3NKKjH
+JM1lbSaGiPCLq6JYi/yRRWZJA3lE89nWC0ls5tIlgwweH2HkuFOrx4pYpsHOpAS0
+PzZI1QJQhbMsTK/3iIW+8c8y281SI5BxK60Evhi+fWdNC7zWkoKupCeY8XLMFvJd
+83j6dg3FE4ilhwI+QaKiNrmQB09TuZwXBWWb2m30Yqs9BXqK/uPDHjECAwEAAaBB
+MD8GCSqGSIb3DQEJDjEyMDAwLgYDVR0RBCcwJYIQdGVzdC5leGFtcGxlLmNvbYIR
+b3RoZXIuZXhhbXBsZS5jb20wDQYJKoZIhvcNAQEFBQADggEBALmXSlN+DxRGrtdv
+/BozsUDHrmQGyC21WqDov46vkuF9rTxrwMbSy8SY5yz61tXud9xemZ0zI9D3YTDv
+hgCzCEokzlqGjZGVhLxLFjNGHpI/evvw8ifDB+OwthykiO9paZ8W/Ux5RmP5hIqn
+Fo2A7qWoVKKkC0sLpzij6dUUDwwaXSWT+m4plXEwkMoVokEt4JcLNrJMNmYWJD0m
+wCZqyBBXynmxt67klTi5dWYJO0Axh39tcx/uGLPeyJwReADrVmNd+KNYqkTRlFBG
+/xl3foX4fLqkuSU8iroZwRC8tkOvrWB2Lc1d74ZKHbAKkYogmM3InkPVfJyp4ovz
+hv6kABo=
+-----END CERTIFICATE REQUEST-----
diff --git a/gcr/tests/frob-request.c b/gcr/tests/frob-request.c
new file mode 100644
index 0000000..68b5d0e
--- /dev/null
+++ b/gcr/tests/frob-request.c
@@ -0,0 +1,96 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * 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.
+ *
+ * Author: Stef Walter <stefw collabora co uk>
+ */
+
+#include "config.h"
+
+#include "gcr/gcr.h"
+#include "gcr/gcr-certificate-req-renderer.h"
+
+#include <gtk/gtk.h>
+
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+static void
+on_parser_parsed (GcrParser *parser,
+ gpointer user_data)
+{
+ GcrViewer *viewer;
+ GcrRenderer *renderer;
+ GtkDialog *dialog = GTK_DIALOG (user_data);
+
+ viewer = gcr_viewer_new_scrolled ();
+ renderer = _gcr_certificate_req_renderer_new_for_attributes (gcr_parser_get_parsed_label (parser),
+ gcr_parser_get_parsed_attributes (parser));
+ gcr_viewer_add_renderer (viewer, renderer);
+ g_object_unref (renderer);
+ gtk_widget_show (GTK_WIDGET (viewer));
+ gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (dialog)), GTK_WIDGET (viewer));
+
+ gtk_container_set_border_width (GTK_CONTAINER (dialog), 20);
+}
+
+static void
+test_request (const gchar *path)
+{
+ GcrParser *parser;
+ GError *err = NULL;
+ guchar *data;
+ gsize n_data;
+ GtkWidget *dialog;
+
+ if (!g_file_get_contents (path, (gchar**)&data, &n_data, NULL))
+ g_error ("couldn't read file: %s", path);
+
+ dialog = gtk_dialog_new ();
+ g_object_ref_sink (dialog);
+
+ parser = gcr_parser_new ();
+ g_signal_connect (parser, "parsed", G_CALLBACK (on_parser_parsed), dialog);
+ 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);
+
+ gtk_widget_show (dialog);
+ g_signal_connect (dialog, "delete-event", G_CALLBACK (gtk_main_quit), NULL);
+ gtk_main ();
+
+ g_object_unref (dialog);
+}
+
+int
+main(int argc, char *argv[])
+{
+ gtk_init (&argc, &argv);
+ g_set_prgname ("frob-request");
+
+ if (argc > 1)
+ test_request (argv[1]);
+ else
+ test_request (SRCDIR "/files/der-rsa-2048.p10");
+
+ return 0;
+}
diff --git a/po/POTFILES.in b/po/POTFILES.in
index a3a74eb..c5c8b38 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -7,6 +7,7 @@ gcr/gcr-callback-output-stream.c
gcr/gcr-certificate.c
gcr/gcr-certificate-exporter.c
gcr/gcr-certificate-extensions.c
+gcr/gcr-certificate-req-renderer.c
gcr/gcr-certificate-renderer.c
gcr/gcr-certificate-widget.c
gcr/gcr-display-view.c
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]