Blame ui/gcr-certificate-renderer.c

Packit b00eeb
/*
Packit b00eeb
 * Copyright (C) 2010 Stefan Walter
Packit b00eeb
 *
Packit b00eeb
 * This program is free software; you can redistribute it and/or modify
Packit b00eeb
 * it under the terms of the GNU Lesser General Public License as
Packit b00eeb
 * published by the Free Software Foundation; either version 2.1 of
Packit b00eeb
 * the License, or (at your option) any later version.
Packit b00eeb
 *
Packit b00eeb
 * This program is distributed in the hope that it will be useful, but
Packit b00eeb
 * WITHOUT ANY WARRANTY; without even the implied warranty of
Packit b00eeb
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit b00eeb
 * Lesser General Public License for more details.
Packit b00eeb
 *
Packit b00eeb
 * You should have received a copy of the GNU Lesser General Public
Packit b00eeb
 * License along with this program; if not, see <http://www.gnu.org/licenses/>.
Packit b00eeb
 */
Packit b00eeb
Packit b00eeb
#include "config.h"
Packit b00eeb
Packit b00eeb
#include "gcr/gcr-certificate.h"
Packit b00eeb
#include "gcr/gcr-certificate-extensions.h"
Packit b00eeb
#include "gcr/gcr-fingerprint.h"
Packit b00eeb
#include "gcr/gcr-icons.h"
Packit b00eeb
#include "gcr/gcr-oids.h"
Packit b00eeb
#include "gcr/gcr-simple-certificate.h"
Packit b00eeb
Packit b00eeb
#include "gcr-certificate-exporter.h"
Packit b00eeb
#include "gcr-certificate-renderer.h"
Packit b00eeb
#include "gcr-certificate-renderer-private.h"
Packit b00eeb
#include "gcr-deprecated.h"
Packit b00eeb
#include "gcr-display-view.h"
Packit b00eeb
#include "gcr-renderer.h"
Packit b00eeb
Packit b00eeb
#include "egg/egg-asn1x.h"
Packit b00eeb
#include "egg/egg-asn1-defs.h"
Packit b00eeb
#include "egg/egg-dn.h"
Packit b00eeb
#include "egg/egg-oid.h"
Packit b00eeb
#include "egg/egg-hex.h"
Packit b00eeb
Packit b00eeb
#include "gck/gck.h"
Packit b00eeb
Packit b00eeb
#include <gdk/gdk.h>
Packit b00eeb
#include <glib/gi18n-lib.h>
Packit b00eeb
Packit b00eeb
/**
Packit b00eeb
 * GcrCertificateRenderer:
Packit b00eeb
 *
Packit b00eeb
 * An implementation of #GcrRenderer which renders certificates.
Packit b00eeb
 */
Packit b00eeb
Packit b00eeb
/**
Packit b00eeb
 * GcrCertificateRendererClass:
Packit b00eeb
 * @parent_class: The parent class.
Packit b00eeb
 *
Packit b00eeb
 * The class for #GcrCertificateRenderer.
Packit b00eeb
 */
Packit b00eeb
Packit b00eeb
enum {
Packit b00eeb
	PROP_0,
Packit b00eeb
	PROP_CERTIFICATE,
Packit b00eeb
	PROP_LABEL,
Packit b00eeb
	PROP_ATTRIBUTES
Packit b00eeb
};
Packit b00eeb
Packit b00eeb
struct _GcrCertificateRendererPrivate {
Packit b00eeb
	GcrCertificate *opt_cert;
Packit b00eeb
	GckAttributes *opt_attrs;
Packit b00eeb
	guint key_size;
Packit b00eeb
	gchar *label;
Packit b00eeb
};
Packit b00eeb
Packit b00eeb
static void gcr_renderer_iface_init (GcrRendererIface *iface);
Packit b00eeb
static void gcr_renderer_certificate_iface_init (GcrCertificateIface *iface);
Packit b00eeb
Packit b00eeb
G_DEFINE_TYPE_WITH_CODE (GcrCertificateRenderer, gcr_certificate_renderer, G_TYPE_OBJECT,
Packit b00eeb
	G_IMPLEMENT_INTERFACE (GCR_TYPE_RENDERER, gcr_renderer_iface_init);
Packit b00eeb
	GCR_CERTIFICATE_MIXIN_IMPLEMENT_COMPARABLE ();
Packit b00eeb
	G_IMPLEMENT_INTERFACE (GCR_TYPE_CERTIFICATE, gcr_renderer_certificate_iface_init);
Packit b00eeb
);
Packit b00eeb
Packit b00eeb
/* -----------------------------------------------------------------------------
Packit b00eeb
 * INTERNAL
Packit b00eeb
 */
Packit b00eeb
Packit b00eeb
static gchar*
Packit b00eeb
calculate_label (GcrCertificateRenderer *self)
Packit b00eeb
{
Packit b00eeb
	gchar *label;
Packit b00eeb
Packit b00eeb
	if (self->pv->label)
Packit b00eeb
		return g_strdup (self->pv->label);
Packit b00eeb
Packit b00eeb
	if (self->pv->opt_attrs) {
Packit b00eeb
		if (gck_attributes_find_string (self->pv->opt_attrs, CKA_LABEL, &label))
Packit b00eeb
			return label;
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	label = gcr_certificate_get_subject_cn (GCR_CERTIFICATE (self));
Packit b00eeb
	if (label != NULL)
Packit b00eeb
		return label;
Packit b00eeb
Packit b00eeb
	return g_strdup (_("Certificate"));
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static gboolean
Packit b00eeb
append_extension_basic_constraints (GcrRenderer *renderer,
Packit b00eeb
                                    GcrDisplayView *view,
Packit b00eeb
                                    GBytes *data)
Packit b00eeb
{
Packit b00eeb
	gboolean is_ca = FALSE;
Packit b00eeb
	gint path_len = -1;
Packit b00eeb
	gchar *number;
Packit b00eeb
Packit b00eeb
	if (!_gcr_certificate_extension_basic_constraints (data, &is_ca, &path_len))
Packit b00eeb
		return FALSE;
Packit b00eeb
Packit b00eeb
	_gcr_display_view_append_heading (view, renderer, _("Basic Constraints"));
Packit b00eeb
Packit b00eeb
	_gcr_display_view_append_value (view, renderer, _("Certificate Authority"),
Packit b00eeb
	                                is_ca ? _("Yes") : _("No"), FALSE);
Packit b00eeb
Packit b00eeb
	number = g_strdup_printf ("%d", path_len);
Packit b00eeb
	_gcr_display_view_append_value (view, renderer, _("Max Path Length"),
Packit b00eeb
	                                path_len < 0 ? _("Unlimited") : number, FALSE);
Packit b00eeb
	g_free (number);
Packit b00eeb
Packit b00eeb
	return TRUE;
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static gboolean
Packit b00eeb
append_extension_extended_key_usage (GcrRenderer *renderer,
Packit b00eeb
                                     GcrDisplayView *view,
Packit b00eeb
                                     GBytes *data)
Packit b00eeb
{
Packit b00eeb
	GQuark *oids;
Packit b00eeb
	GString *text;
Packit b00eeb
	guint i;
Packit b00eeb
Packit b00eeb
	oids = _gcr_certificate_extension_extended_key_usage (data);
Packit b00eeb
	if (oids == NULL)
Packit b00eeb
		return FALSE;
Packit b00eeb
Packit b00eeb
	_gcr_display_view_append_heading (view, renderer, _("Extended Key Usage"));
Packit b00eeb
Packit b00eeb
	text = g_string_new ("");
Packit b00eeb
	for (i = 0; oids[i] != 0; i++) {
Packit b00eeb
		if (i > 0)
Packit b00eeb
			g_string_append_unichar (text, GCR_DISPLAY_VIEW_LINE_BREAK);
Packit b00eeb
		g_string_append (text, egg_oid_get_description (oids[i]));
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	g_free (oids);
Packit b00eeb
Packit b00eeb
	_gcr_display_view_append_value (view, renderer, _("Allowed Purposes"),
Packit b00eeb
	                                text->str, FALSE);
Packit b00eeb
Packit b00eeb
	g_string_free (text, TRUE);
Packit b00eeb
Packit b00eeb
	return TRUE;
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static gboolean
Packit b00eeb
append_extension_subject_key_identifier (GcrRenderer *renderer,
Packit b00eeb
                                         GcrDisplayView *view,
Packit b00eeb
                                         GBytes *data)
Packit b00eeb
{
Packit b00eeb
	gpointer keyid;
Packit b00eeb
	gsize n_keyid;
Packit b00eeb
Packit b00eeb
	keyid = _gcr_certificate_extension_subject_key_identifier (data, &n_keyid);
Packit b00eeb
	if (keyid == NULL)
Packit b00eeb
		return FALSE;
Packit b00eeb
Packit b00eeb
	_gcr_display_view_append_heading (view, renderer, _("Subject Key Identifier"));
Packit b00eeb
	_gcr_display_view_append_hex (view, renderer, _("Key Identifier"), keyid, n_keyid);
Packit b00eeb
Packit b00eeb
	g_free (keyid);
Packit b00eeb
Packit b00eeb
	return TRUE;
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static const struct {
Packit b00eeb
	guint usage;
Packit b00eeb
	const gchar *description;
Packit b00eeb
} usage_descriptions[] = {
Packit b00eeb
	{ GCR_KEY_USAGE_DIGITAL_SIGNATURE, N_("Digital signature") },
Packit b00eeb
	{ GCR_KEY_USAGE_KEY_ENCIPHERMENT, N_("Key encipherment") },
Packit b00eeb
	{ GCR_KEY_USAGE_DATA_ENCIPHERMENT, N_("Data encipherment") },
Packit b00eeb
	{ GCR_KEY_USAGE_KEY_AGREEMENT, N_("Key agreement") },
Packit b00eeb
	{ GCR_KEY_USAGE_KEY_CERT_SIGN, N_("Certificate signature") },
Packit b00eeb
	{ GCR_KEY_USAGE_CRL_SIGN, N_("Revocation list signature") }
Packit b00eeb
};
Packit b00eeb
Packit b00eeb
static gboolean
Packit b00eeb
append_extension_key_usage (GcrRenderer *renderer,
Packit b00eeb
                            GcrDisplayView *view,
Packit b00eeb
                            GBytes *data)
Packit b00eeb
{
Packit b00eeb
	gulong key_usage;
Packit b00eeb
	GString *text;
Packit b00eeb
	guint i;
Packit b00eeb
Packit b00eeb
	if (!_gcr_certificate_extension_key_usage (data, &key_usage))
Packit b00eeb
		return FALSE;
Packit b00eeb
Packit b00eeb
	text = g_string_new ("");
Packit b00eeb
Packit b00eeb
	for (i = 0; i < G_N_ELEMENTS (usage_descriptions); i++) {
Packit b00eeb
		if (key_usage & usage_descriptions[i].usage) {
Packit b00eeb
			if (text->len > 0)
Packit b00eeb
				g_string_append_unichar (text, GCR_DISPLAY_VIEW_LINE_BREAK);
Packit b00eeb
			g_string_append (text, _(usage_descriptions[i].description));
Packit b00eeb
		}
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	_gcr_display_view_append_heading (view, renderer, _("Key Usage"));
Packit b00eeb
	_gcr_display_view_append_value (view, renderer, _("Usages"), text->str, FALSE);
Packit b00eeb
Packit b00eeb
	g_string_free (text, TRUE);
Packit b00eeb
Packit b00eeb
	return TRUE;
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static gboolean
Packit b00eeb
append_extension_subject_alt_name (GcrRenderer *renderer,
Packit b00eeb
                                   GcrDisplayView *view,
Packit b00eeb
                                   GBytes *data)
Packit b00eeb
{
Packit b00eeb
	GArray *general_names;
Packit b00eeb
	GcrGeneralName *general;
Packit b00eeb
	guint i;
Packit b00eeb
Packit b00eeb
	general_names = _gcr_certificate_extension_subject_alt_name (data);
Packit b00eeb
	if (general_names == NULL)
Packit b00eeb
		return FALSE;
Packit b00eeb
Packit b00eeb
	_gcr_display_view_append_heading (view, renderer, _("Subject Alternative Names"));
Packit b00eeb
Packit b00eeb
	for (i = 0; i < general_names->len; i++) {
Packit b00eeb
		general = &g_array_index (general_names, GcrGeneralName, i);
Packit b00eeb
		if (general->display == NULL)
Packit b00eeb
			_gcr_display_view_append_hex (view, renderer, general->description,
Packit b00eeb
			                              g_bytes_get_data (general->raw, NULL),
Packit b00eeb
			                              g_bytes_get_size (general->raw));
Packit b00eeb
		else
Packit b00eeb
			_gcr_display_view_append_value (view, renderer, general->description,
Packit b00eeb
			                                general->display, FALSE);
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	_gcr_general_names_free (general_names);
Packit b00eeb
Packit b00eeb
	return TRUE;
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static gboolean
Packit b00eeb
append_extension_hex (GcrRenderer *renderer,
Packit b00eeb
                      GcrDisplayView *view,
Packit b00eeb
                      GQuark oid,
Packit b00eeb
                      gconstpointer data,
Packit b00eeb
                      gsize n_data)
Packit b00eeb
{
Packit b00eeb
	const gchar *text;
Packit b00eeb
Packit b00eeb
	_gcr_display_view_append_heading (view, renderer, _("Extension"));
Packit b00eeb
Packit b00eeb
	/* Extension type */
Packit b00eeb
	text = egg_oid_get_description (oid);
Packit b00eeb
	_gcr_display_view_append_value (view, renderer, _("Identifier"), text, FALSE);
Packit b00eeb
	_gcr_display_view_append_hex (view, renderer, _("Value"), data, n_data);
Packit b00eeb
Packit b00eeb
	return TRUE;
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
on_export_completed (GObject *source, GAsyncResult *result, gpointer user_data)
Packit b00eeb
{
Packit b00eeb
	GtkWindow *parent = GTK_WINDOW (user_data);
Packit b00eeb
	GcrCertificateExporter *exporter = GCR_CERTIFICATE_EXPORTER (source);
Packit b00eeb
	GError *error = NULL;
Packit b00eeb
	GtkWidget *dialog;
Packit b00eeb
Packit b00eeb
	if (!_gcr_certificate_exporter_export_finish (exporter, result, &error)) {
Packit b00eeb
		if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
Packit b00eeb
			dialog = gtk_message_dialog_new_with_markup (parent,
Packit b00eeb
				  GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR,
Packit b00eeb
				  GTK_BUTTONS_OK, "<big>%s</big>\n\n%s",
Packit b00eeb
				  _("Couldn’t export the certificate."),
Packit b00eeb
				  error->message);
Packit b00eeb
			gtk_widget_show (dialog);
Packit b00eeb
			g_signal_connect (dialog, "delete-event",
Packit b00eeb
					  G_CALLBACK (gtk_widget_destroy), dialog);
Packit b00eeb
			g_signal_connect_swapped(dialog, "response", G_CALLBACK (gtk_widget_destroy), dialog);
Packit b00eeb
		}
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	/* Matches ref in on_certificate_export */
Packit b00eeb
	if (parent)
Packit b00eeb
		g_object_unref (parent);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
on_certificate_export (GtkMenuItem *menuitem, gpointer user_data)
Packit b00eeb
{
Packit b00eeb
	GcrCertificateRenderer *self = GCR_CERTIFICATE_RENDERER (user_data);
Packit b00eeb
	GcrCertificateExporter *exporter;
Packit b00eeb
	gchar *label;
Packit b00eeb
	GtkWidget *parent;
Packit b00eeb
Packit b00eeb
	label = calculate_label (self);
Packit b00eeb
Packit b00eeb
	parent = gtk_widget_get_toplevel (GTK_WIDGET (menuitem));
Packit b00eeb
	if (parent && !GTK_IS_WINDOW (parent))
Packit b00eeb
		parent = NULL;
Packit b00eeb
Packit b00eeb
	exporter = _gcr_certificate_exporter_new (GCR_CERTIFICATE (self), label,
Packit b00eeb
	                                          GTK_WINDOW (parent));
Packit b00eeb
Packit b00eeb
	g_free (label);
Packit b00eeb
Packit b00eeb
	_gcr_certificate_exporter_export_async (exporter, NULL, on_export_completed,
Packit b00eeb
	                                        parent ? g_object_ref (parent) : NULL);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
/* -----------------------------------------------------------------------------
Packit b00eeb
 * OBJECT
Packit b00eeb
 */
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
gcr_certificate_renderer_init (GcrCertificateRenderer *self)
Packit b00eeb
{
Packit b00eeb
	self->pv = (G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_CERTIFICATE_RENDERER, GcrCertificateRendererPrivate));
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
gcr_certificate_renderer_dispose (GObject *obj)
Packit b00eeb
{
Packit b00eeb
	GcrCertificateRenderer *self = GCR_CERTIFICATE_RENDERER (obj);
Packit b00eeb
Packit b00eeb
	if (self->pv->opt_cert)
Packit b00eeb
		g_object_unref (self->pv->opt_cert);
Packit b00eeb
	self->pv->opt_cert = NULL;
Packit b00eeb
Packit b00eeb
	G_OBJECT_CLASS (gcr_certificate_renderer_parent_class)->dispose (obj);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
gcr_certificate_renderer_finalize (GObject *obj)
Packit b00eeb
{
Packit b00eeb
	GcrCertificateRenderer *self = GCR_CERTIFICATE_RENDERER (obj);
Packit b00eeb
Packit b00eeb
	g_assert (!self->pv->opt_cert);
Packit b00eeb
Packit b00eeb
	if (self->pv->opt_attrs)
Packit b00eeb
		gck_attributes_unref (self->pv->opt_attrs);
Packit b00eeb
	self->pv->opt_attrs = NULL;
Packit b00eeb
Packit b00eeb
	g_free (self->pv->label);
Packit b00eeb
	self->pv->label = NULL;
Packit b00eeb
Packit b00eeb
	G_OBJECT_CLASS (gcr_certificate_renderer_parent_class)->finalize (obj);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
gcr_certificate_renderer_set_property (GObject *obj, guint prop_id, const GValue *value,
Packit b00eeb
                                     GParamSpec *pspec)
Packit b00eeb
{
Packit b00eeb
	GcrCertificateRenderer *self = GCR_CERTIFICATE_RENDERER (obj);
Packit b00eeb
Packit b00eeb
	switch (prop_id) {
Packit b00eeb
	case PROP_CERTIFICATE:
Packit b00eeb
		gcr_certificate_renderer_set_certificate (self, g_value_get_object (value));
Packit b00eeb
		break;
Packit b00eeb
	case PROP_LABEL:
Packit b00eeb
		g_free (self->pv->label);
Packit b00eeb
		self->pv->label = g_value_dup_string (value);
Packit b00eeb
		g_object_notify (obj, "label");
Packit b00eeb
		gcr_renderer_emit_data_changed (GCR_RENDERER (self));
Packit b00eeb
		break;
Packit b00eeb
	case PROP_ATTRIBUTES:
Packit b00eeb
		gck_attributes_unref (self->pv->opt_attrs);
Packit b00eeb
		self->pv->opt_attrs = g_value_get_boxed (value);
Packit b00eeb
		if (self->pv->opt_attrs)
Packit b00eeb
			gck_attributes_ref (self->pv->opt_attrs);
Packit b00eeb
		if (self->pv->opt_cert) {
Packit b00eeb
			g_object_unref (self->pv->opt_cert);
Packit b00eeb
			g_object_notify (G_OBJECT (self), "certificate");
Packit b00eeb
			self->pv->opt_cert = NULL;
Packit b00eeb
		}
Packit b00eeb
		gcr_renderer_emit_data_changed (GCR_RENDERER (self));
Packit b00eeb
		g_object_notify (G_OBJECT (self), "attributes");
Packit b00eeb
		break;
Packit b00eeb
	default:
Packit b00eeb
		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
Packit b00eeb
		break;
Packit b00eeb
	}
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
gcr_certificate_renderer_get_property (GObject *obj, guint prop_id, GValue *value,
Packit b00eeb
                                     GParamSpec *pspec)
Packit b00eeb
{
Packit b00eeb
	GcrCertificateRenderer *self = GCR_CERTIFICATE_RENDERER (obj);
Packit b00eeb
Packit b00eeb
	switch (prop_id) {
Packit b00eeb
	case PROP_CERTIFICATE:
Packit b00eeb
		g_value_set_object (value, self->pv->opt_cert);
Packit b00eeb
		break;
Packit b00eeb
	case PROP_LABEL:
Packit b00eeb
		g_value_take_string (value, calculate_label (self));
Packit b00eeb
		break;
Packit b00eeb
	case PROP_ATTRIBUTES:
Packit b00eeb
		g_value_set_boxed (value, self->pv->opt_attrs);
Packit b00eeb
		break;
Packit b00eeb
	default:
Packit b00eeb
		gcr_certificate_mixin_get_property (obj, prop_id, value, pspec);
Packit b00eeb
		break;
Packit b00eeb
	}
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
gcr_certificate_renderer_class_init (GcrCertificateRendererClass *klass)
Packit b00eeb
{
Packit b00eeb
	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
Packit b00eeb
	GckBuilder builder = GCK_BUILDER_INIT;
Packit b00eeb
Packit b00eeb
	gcr_certificate_renderer_parent_class = g_type_class_peek_parent (klass);
Packit b00eeb
	g_type_class_add_private (klass, sizeof (GcrCertificateRendererPrivate));
Packit b00eeb
Packit b00eeb
	gobject_class->dispose = gcr_certificate_renderer_dispose;
Packit b00eeb
	gobject_class->finalize = gcr_certificate_renderer_finalize;
Packit b00eeb
	gobject_class->set_property = gcr_certificate_renderer_set_property;
Packit b00eeb
	gobject_class->get_property = gcr_certificate_renderer_get_property;
Packit b00eeb
Packit b00eeb
	/**
Packit b00eeb
	 * GcrCertificateRenderer:certificate:
Packit b00eeb
	 *
Packit b00eeb
	 * The certificate to display. May be %NULL.
Packit b00eeb
	 */
Packit b00eeb
	g_object_class_install_property (gobject_class, PROP_CERTIFICATE,
Packit b00eeb
	           g_param_spec_object ("certificate", "Certificate", "Certificate to display.",
Packit b00eeb
	                                GCR_TYPE_CERTIFICATE, G_PARAM_READWRITE));
Packit b00eeb
Packit b00eeb
	/**
Packit b00eeb
	 * GcrCertificateRenderer:attributes:
Packit b00eeb
	 *
Packit b00eeb
	 * The certificate attributes to display. One of the attributes must be
Packit b00eeb
	 * a CKA_VALUE type attribute which contains a DER encoded certificate.
Packit b00eeb
	 */
Packit b00eeb
	g_object_class_install_property (gobject_class, PROP_ATTRIBUTES,
Packit b00eeb
	           g_param_spec_boxed ("attributes", "Attributes", "Certificate pkcs11 attributes",
Packit b00eeb
	                               GCK_TYPE_ATTRIBUTES, G_PARAM_READWRITE));
Packit b00eeb
Packit b00eeb
	/**
Packit b00eeb
	 * GcrCertificateRenderer:label:
Packit b00eeb
	 *
Packit b00eeb
	 * The label to display.
Packit b00eeb
	 */
Packit b00eeb
	g_object_class_install_property (gobject_class, PROP_LABEL,
Packit b00eeb
	           g_param_spec_string ("label", "Label", "Certificate Label",
Packit b00eeb
	                                "", G_PARAM_READWRITE));
Packit b00eeb
Packit b00eeb
	gcr_certificate_mixin_class_init (gobject_class);
Packit b00eeb
Packit b00eeb
	/* Register this as a renderer which can be loaded */
Packit b00eeb
	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_CERTIFICATE);
Packit b00eeb
	gcr_renderer_register (GCR_TYPE_CERTIFICATE_RENDERER, gck_builder_end (&builder));
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
gcr_certificate_renderer_render (GcrRenderer *renderer, GcrViewer *viewer)
Packit b00eeb
{
Packit b00eeb
	GcrCertificateRenderer *self;
Packit b00eeb
	GNode *extension;
Packit b00eeb
	gconstpointer data;
Packit b00eeb
	gsize n_data;
Packit b00eeb
	GcrDisplayView *view;
Packit b00eeb
	GcrCertificate *cert;
Packit b00eeb
	GBytes *number;
Packit b00eeb
	gulong version;
Packit b00eeb
	guint bits, index;
Packit b00eeb
	gchar *display;
Packit b00eeb
	GBytes *bytes;
Packit b00eeb
	GNode *asn;
Packit b00eeb
	GDate date;
Packit b00eeb
	GIcon *icon;
Packit b00eeb
Packit b00eeb
	self = GCR_CERTIFICATE_RENDERER (renderer);
Packit b00eeb
Packit b00eeb
	if (GCR_IS_DISPLAY_VIEW (viewer)) {
Packit b00eeb
		view = GCR_DISPLAY_VIEW (viewer);
Packit b00eeb
Packit b00eeb
	} else {
Packit b00eeb
		g_warning ("GcrCertificateRenderer only works with internal specific "
Packit b00eeb
		           "GcrViewer returned by gcr_viewer_new().");
Packit b00eeb
		return;
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	_gcr_display_view_begin (view, renderer);
Packit b00eeb
	cert = GCR_CERTIFICATE (self);
Packit b00eeb
Packit b00eeb
	data = gcr_certificate_get_der_data (cert, &n_data);
Packit b00eeb
	if (!data) {
Packit b00eeb
		_gcr_display_view_end (view, renderer);
Packit b00eeb
		return;
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	icon = gcr_certificate_get_icon (cert);
Packit b00eeb
	_gcr_display_view_set_icon (view, GCR_RENDERER (self), icon);
Packit b00eeb
	g_object_unref (icon);
Packit b00eeb
Packit b00eeb
	bytes = g_bytes_new_static (data, n_data);
Packit b00eeb
	asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", bytes);
Packit b00eeb
	g_return_if_fail (asn != NULL);
Packit b00eeb
	g_bytes_unref (bytes);
Packit b00eeb
Packit b00eeb
	display = calculate_label (self);
Packit b00eeb
	_gcr_display_view_append_title (view, renderer, display);
Packit b00eeb
	g_free (display);
Packit b00eeb
Packit b00eeb
	display = egg_dn_read_part (egg_asn1x_node (asn, "tbsCertificate", "subject", "rdnSequence", NULL), "CN");
Packit b00eeb
	_gcr_display_view_append_content (view, renderer, _("Identity"), display);
Packit b00eeb
	g_free (display);
Packit b00eeb
Packit b00eeb
	display = egg_dn_read_part (egg_asn1x_node (asn, "tbsCertificate", "issuer", "rdnSequence", NULL), "CN");
Packit b00eeb
	_gcr_display_view_append_content (view, renderer, _("Verified by"), display);
Packit b00eeb
	g_free (display);
Packit b00eeb
Packit b00eeb
	if (egg_asn1x_get_time_as_date (egg_asn1x_node (asn, "tbsCertificate", "validity", "notAfter", NULL), &date)) {
Packit b00eeb
		display = g_malloc0 (128);
Packit b00eeb
		if (!g_date_strftime (display, 128, "%x", &date))
Packit b00eeb
			g_return_if_reached ();
Packit b00eeb
		_gcr_display_view_append_content (view, renderer, _("Expires"), display);
Packit b00eeb
		g_free (display);
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	_gcr_display_view_start_details (view, renderer);
Packit b00eeb
Packit b00eeb
	/* The subject */
Packit b00eeb
	_gcr_display_view_append_heading (view, renderer, _("Subject Name"));
Packit b00eeb
	_gcr_certificate_renderer_append_distinguished_name (renderer, view,
Packit b00eeb
	                                                     egg_asn1x_node (asn, "tbsCertificate", "subject", "rdnSequence", NULL));
Packit b00eeb
Packit b00eeb
	/* The Issuer */
Packit b00eeb
	_gcr_display_view_append_heading (view, renderer, _("Issuer Name"));
Packit b00eeb
	_gcr_certificate_renderer_append_distinguished_name (renderer, view,
Packit b00eeb
	                                                     egg_asn1x_node (asn, "tbsCertificate", "issuer", "rdnSequence", NULL));
Packit b00eeb
Packit b00eeb
	/* The Issued Parameters */
Packit b00eeb
	_gcr_display_view_append_heading (view, renderer, _("Issued Certificate"));
Packit b00eeb
Packit b00eeb
	if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "tbsCertificate", "version", NULL), &version))
Packit b00eeb
		g_return_if_reached ();
Packit b00eeb
	display = g_strdup_printf ("%lu", version + 1);
Packit b00eeb
	_gcr_display_view_append_value (view, renderer, _("Version"), display, FALSE);
Packit b00eeb
	g_free (display);
Packit b00eeb
Packit b00eeb
	number = egg_asn1x_get_integer_as_raw (egg_asn1x_node (asn, "tbsCertificate", "serialNumber", NULL));
Packit b00eeb
	g_return_if_fail (number != NULL);
Packit b00eeb
	_gcr_display_view_append_hex (view, renderer, _("Serial Number"),
Packit b00eeb
	                              g_bytes_get_data (number, NULL),
Packit b00eeb
	                              g_bytes_get_size (number));
Packit b00eeb
	g_bytes_unref (number);
Packit b00eeb
Packit b00eeb
	display = g_malloc0 (128);
Packit b00eeb
	if (egg_asn1x_get_time_as_date (egg_asn1x_node (asn, "tbsCertificate", "validity", "notBefore", NULL), &date)) {
Packit b00eeb
		if (!g_date_strftime (display, 128, "%Y-%m-%d", &date))
Packit b00eeb
			g_return_if_reached ();
Packit b00eeb
		_gcr_display_view_append_value (view, renderer, _("Not Valid Before"), display, FALSE);
Packit b00eeb
	}
Packit b00eeb
	if (egg_asn1x_get_time_as_date (egg_asn1x_node (asn, "tbsCertificate", "validity", "notAfter", NULL), &date)) {
Packit b00eeb
		if (!g_date_strftime (display, 128, "%Y-%m-%d", &date))
Packit b00eeb
			g_return_if_reached ();
Packit b00eeb
		_gcr_display_view_append_value (view, renderer, _("Not Valid After"), display, FALSE);
Packit b00eeb
	}
Packit b00eeb
	g_free (display);
Packit b00eeb
Packit b00eeb
	/* Fingerprints */
Packit b00eeb
	_gcr_display_view_append_heading (view, renderer, _("Certificate Fingerprints"));
Packit b00eeb
Packit b00eeb
	_gcr_display_view_append_fingerprint (view, renderer, data, n_data, "SHA1", G_CHECKSUM_SHA1);
Packit b00eeb
	_gcr_display_view_append_fingerprint (view, renderer, data, n_data, "MD5", G_CHECKSUM_MD5);
Packit b00eeb
Packit b00eeb
	/* Public Key Info */
Packit b00eeb
	_gcr_display_view_append_heading (view, renderer, _("Public Key Info"));
Packit b00eeb
	bits = gcr_certificate_get_key_size (cert);
Packit b00eeb
	_gcr_certificate_renderer_append_subject_public_key (renderer, view, bits,
Packit b00eeb
	                                                     egg_asn1x_node (asn, "tbsCertificate",
Packit b00eeb
	                                                                     "subjectPublicKeyInfo", NULL));
Packit b00eeb
Packit b00eeb
	/* Extensions */
Packit b00eeb
	for (index = 1; TRUE; ++index) {
Packit b00eeb
		extension = egg_asn1x_node (asn, "tbsCertificate", "extensions", index, NULL);
Packit b00eeb
		if (extension == NULL)
Packit b00eeb
			break;
Packit b00eeb
		_gcr_certificate_renderer_append_extension (renderer, view, extension);
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	/* Signature */
Packit b00eeb
	_gcr_display_view_append_heading (view, renderer, _("Signature"));
Packit b00eeb
	_gcr_certificate_renderer_append_signature (renderer, view, asn);
Packit b00eeb
Packit b00eeb
	egg_asn1x_destroy (asn);
Packit b00eeb
	_gcr_display_view_end (view, renderer);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
gcr_certificate_renderer_populate_popup (GcrRenderer *self, GcrViewer *viewer,
Packit b00eeb
                                         GtkMenu *menu)
Packit b00eeb
{
Packit b00eeb
	GtkWidget *item;
Packit b00eeb
Packit b00eeb
	item = gtk_separator_menu_item_new ();
Packit b00eeb
	gtk_widget_show (item);
Packit b00eeb
	gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
Packit b00eeb
Packit b00eeb
	item = gtk_menu_item_new_with_label (_("Export Certificate\xE2\x80\xA6"));
Packit b00eeb
	gtk_widget_show (item);
Packit b00eeb
	g_signal_connect_data (item, "activate", G_CALLBACK (on_certificate_export),
Packit b00eeb
	                       g_object_ref (self), (GClosureNotify)g_object_unref, 0);
Packit b00eeb
	gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
gcr_renderer_iface_init (GcrRendererIface *iface)
Packit b00eeb
{
Packit b00eeb
	iface->populate_popup = gcr_certificate_renderer_populate_popup;
Packit b00eeb
	iface->render_view = gcr_certificate_renderer_render;
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static const guchar *
Packit b00eeb
gcr_certificate_renderer_get_der_data (GcrCertificate *cert,
Packit b00eeb
                                       gsize *n_data)
Packit b00eeb
{
Packit b00eeb
	GcrCertificateRenderer *self = GCR_CERTIFICATE_RENDERER (cert);
Packit b00eeb
	const GckAttribute *attr;
Packit b00eeb
Packit b00eeb
	g_assert (n_data);
Packit b00eeb
Packit b00eeb
	if (self->pv->opt_cert)
Packit b00eeb
		return gcr_certificate_get_der_data (self->pv->opt_cert, n_data);
Packit b00eeb
Packit b00eeb
	if (self->pv->opt_attrs) {
Packit b00eeb
		attr = gck_attributes_find (self->pv->opt_attrs, CKA_VALUE);
Packit b00eeb
		g_return_val_if_fail (attr, NULL);
Packit b00eeb
		*n_data = attr->length;
Packit b00eeb
		return attr->value;
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	return NULL;
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
gcr_renderer_certificate_iface_init (GcrCertificateIface *iface)
Packit b00eeb
{
Packit b00eeb
	iface->get_der_data = gcr_certificate_renderer_get_der_data;
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
/* -----------------------------------------------------------------------------
Packit b00eeb
 * PUBLIC
Packit b00eeb
 */
Packit b00eeb
Packit b00eeb
/**
Packit b00eeb
 * gcr_certificate_renderer_new:
Packit b00eeb
 * @certificate: The certificate to display
Packit b00eeb
 *
Packit b00eeb
 * Create a new certificate renderer to display the certificate.
Packit b00eeb
 *
Packit b00eeb
 * Returns: (transfer full): a newly allocated #GcrCertificateRenderer, which
Packit b00eeb
 *          should be released with g_object_unref()
Packit b00eeb
 */
Packit b00eeb
GcrCertificateRenderer *
Packit b00eeb
gcr_certificate_renderer_new (GcrCertificate *certificate)
Packit b00eeb
{
Packit b00eeb
	return g_object_new (GCR_TYPE_CERTIFICATE_RENDERER, "certificate", certificate, NULL);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
/**
Packit b00eeb
 * gcr_certificate_renderer_new_for_attributes:
Packit b00eeb
 * @label: (allow-none): the label to display
Packit b00eeb
 * @attrs: The attributes to display
Packit b00eeb
 *
Packit b00eeb
 * Create a new certificate renderer to display the label and attributes. One
Packit b00eeb
 * of the attributes should be a CKA_VALUE type attribute containing a DER
Packit b00eeb
 * encoded certificate.
Packit b00eeb
 *
Packit b00eeb
 * Returns: (transfer full): a newly allocated #GcrCertificateRenderer, which
Packit b00eeb
 *          should be released with g_object_unref()
Packit b00eeb
 */
Packit b00eeb
GcrCertificateRenderer *
Packit b00eeb
gcr_certificate_renderer_new_for_attributes (const gchar *label, struct _GckAttributes *attrs)
Packit b00eeb
{
Packit b00eeb
	return g_object_new (GCR_TYPE_CERTIFICATE_RENDERER, "label", label, "attributes", attrs, NULL);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
/**
Packit b00eeb
 * gcr_certificate_renderer_get_certificate:
Packit b00eeb
 * @self: The renderer
Packit b00eeb
 *
Packit b00eeb
 * Get the certificate displayed in the renderer. If no certificate was
Packit b00eeb
 * explicitly set, then the renderer will return itself since it acts as
Packit b00eeb
 * a valid certificate.
Packit b00eeb
 *
Packit b00eeb
 * Returns: (transfer none): The certificate, owned by the renderer.
Packit b00eeb
 */
Packit b00eeb
GcrCertificate *
Packit b00eeb
gcr_certificate_renderer_get_certificate (GcrCertificateRenderer *self)
Packit b00eeb
{
Packit b00eeb
	g_return_val_if_fail (GCR_IS_CERTIFICATE_RENDERER (self), NULL);
Packit b00eeb
	if (self->pv->opt_cert)
Packit b00eeb
		return self->pv->opt_cert;
Packit b00eeb
	return GCR_CERTIFICATE (self);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
/**
Packit b00eeb
 * gcr_certificate_renderer_set_certificate:
Packit b00eeb
 * @self: The renderer
Packit b00eeb
 * @certificate: (allow-none): the certificate to display
Packit b00eeb
 *
Packit b00eeb
 * Set a certificate to display in the renderer.
Packit b00eeb
 */
Packit b00eeb
void
Packit b00eeb
gcr_certificate_renderer_set_certificate (GcrCertificateRenderer *self, GcrCertificate *certificate)
Packit b00eeb
{
Packit b00eeb
	g_return_if_fail (GCR_IS_CERTIFICATE_RENDERER (self));
Packit b00eeb
Packit b00eeb
	if (self->pv->opt_cert)
Packit b00eeb
		g_object_unref (self->pv->opt_cert);
Packit b00eeb
	self->pv->opt_cert = certificate;
Packit b00eeb
	if (self->pv->opt_cert)
Packit b00eeb
		g_object_ref (self->pv->opt_cert);
Packit b00eeb
Packit b00eeb
	if (self->pv->opt_attrs) {
Packit b00eeb
		gck_attributes_unref (self->pv->opt_attrs);
Packit b00eeb
		self->pv->opt_attrs = NULL;
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	gcr_renderer_emit_data_changed (GCR_RENDERER (self));
Packit b00eeb
	g_object_notify (G_OBJECT (self), "certificate");
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
/**
Packit b00eeb
 * gcr_certificate_renderer_get_attributes:
Packit b00eeb
 * @self: The renderer
Packit b00eeb
 *
Packit b00eeb
 * Get the PKCS\#11 attributes, if any, set for this renderer to display.
Packit b00eeb
 *
Packit b00eeb
 * Returns: (allow-none) (transfer none): the attributes, owned by the renderer
Packit b00eeb
 *
Packit b00eeb
 * Deprecated: 3.6: Use gcr_renderer_get_attributes() instead
Packit b00eeb
 */
Packit b00eeb
GckAttributes *
Packit b00eeb
gcr_certificate_renderer_get_attributes (GcrCertificateRenderer *self)
Packit b00eeb
{
Packit b00eeb
	g_return_val_if_fail (GCR_IS_CERTIFICATE_RENDERER (self), NULL);
Packit b00eeb
	return gcr_renderer_get_attributes (GCR_RENDERER (self));
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
/**
Packit b00eeb
 * gcr_certificate_renderer_set_attributes:
Packit b00eeb
 * @self: The renderer
Packit b00eeb
 * @attrs: (allow-none): attributes to set
Packit b00eeb
 *
Packit b00eeb
 * Set the PKCS\#11 attributes for this renderer to display. One of the attributes
Packit b00eeb
 * should be a CKA_VALUE type attribute containing a DER encoded certificate.
Packit b00eeb
 *
Packit b00eeb
 * Deprecated: 3.6: Use gcr_renderer_set_attributes() instead
Packit b00eeb
 */
Packit b00eeb
void
Packit b00eeb
gcr_certificate_renderer_set_attributes (GcrCertificateRenderer *self, GckAttributes *attrs)
Packit b00eeb
{
Packit b00eeb
	g_return_if_fail (GCR_IS_CERTIFICATE_RENDERER (self));
Packit b00eeb
	gcr_renderer_set_attributes (GCR_RENDERER (self), attrs);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
typedef struct {
Packit b00eeb
	GcrRenderer *renderer;
Packit b00eeb
	GcrDisplayView *view;
Packit b00eeb
} AppendDnClosure;
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
on_parsed_dn_part (guint index,
Packit b00eeb
                   GQuark oid,
Packit b00eeb
                   GNode *value,
Packit b00eeb
                   gpointer user_data)
Packit b00eeb
{
Packit b00eeb
	GcrRenderer *renderer = ((AppendDnClosure *)user_data)->renderer;
Packit b00eeb
	GcrDisplayView *view = ((AppendDnClosure *)user_data)->view;
Packit b00eeb
	const gchar *attr;
Packit b00eeb
	const gchar *desc;
Packit b00eeb
	gchar *field = NULL;
Packit b00eeb
	gchar *display;
Packit b00eeb
Packit b00eeb
	attr = egg_oid_get_name (oid);
Packit b00eeb
	desc = egg_oid_get_description (oid);
Packit b00eeb
Packit b00eeb
	/* Combine them into something sane */
Packit b00eeb
	if (attr && desc) {
Packit b00eeb
		if (strcmp (attr, desc) == 0)
Packit b00eeb
			field = g_strdup (attr);
Packit b00eeb
		else
Packit b00eeb
			field = g_strdup_printf ("%s (%s)", attr, desc);
Packit b00eeb
	} else if (!attr && !desc) {
Packit b00eeb
		field = g_strdup ("");
Packit b00eeb
	} else if (attr) {
Packit b00eeb
		field = g_strdup (attr);
Packit b00eeb
	} else if (desc) {
Packit b00eeb
		field = g_strdup (desc);
Packit b00eeb
	} else {
Packit b00eeb
		g_assert_not_reached ();
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	display = egg_dn_print_value (oid, value);
Packit b00eeb
	if (display == NULL)
Packit b00eeb
		display = g_strdup ("");
Packit b00eeb
Packit b00eeb
	_gcr_display_view_append_value (view, renderer, field, display, FALSE);
Packit b00eeb
	g_free (field);
Packit b00eeb
	g_free (display);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
Packit b00eeb
void
Packit b00eeb
_gcr_certificate_renderer_append_distinguished_name (GcrRenderer *renderer,
Packit b00eeb
                                                     GcrDisplayView *view,
Packit b00eeb
                                                     GNode *dn)
Packit b00eeb
{
Packit b00eeb
	AppendDnClosure closure;
Packit b00eeb
Packit b00eeb
	g_return_if_fail (GCR_IS_RENDERER (renderer));
Packit b00eeb
	g_return_if_fail (GCR_IS_DISPLAY_VIEW (view));
Packit b00eeb
	g_return_if_fail (dn != NULL);
Packit b00eeb
Packit b00eeb
	closure.renderer = renderer;
Packit b00eeb
	closure.view = view;
Packit b00eeb
	egg_dn_parse (dn, on_parsed_dn_part, &closure);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
void
Packit b00eeb
_gcr_certificate_renderer_append_subject_public_key (GcrRenderer *renderer,
Packit b00eeb
                                                     GcrDisplayView *view,
Packit b00eeb
                                                     guint key_nbits,
Packit b00eeb
                                                     GNode *subject_public_key)
Packit b00eeb
{
Packit b00eeb
	const gchar *text;
Packit b00eeb
	gchar *display;
Packit b00eeb
	GBytes *value;
Packit b00eeb
	guchar *raw;
Packit b00eeb
	gsize n_raw;
Packit b00eeb
	GQuark oid;
Packit b00eeb
	guint bits;
Packit b00eeb
Packit b00eeb
	oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (subject_public_key,
Packit b00eeb
	                                                  "algorithm", "algorithm", NULL));
Packit b00eeb
	text = egg_oid_get_description (oid);
Packit b00eeb
	_gcr_display_view_append_value (view, renderer, _("Key Algorithm"), text, FALSE);
Packit b00eeb
Packit b00eeb
	value = egg_asn1x_get_element_raw (egg_asn1x_node (subject_public_key,
Packit b00eeb
	                                                   "algorithm", "parameters", NULL));
Packit b00eeb
	if (value) {
Packit b00eeb
		_gcr_display_view_append_hex (view, renderer, _("Key Parameters"),
Packit b00eeb
		                              g_bytes_get_data (value, NULL),
Packit b00eeb
		                              g_bytes_get_size (value));
Packit b00eeb
		g_bytes_unref (value);
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	if (key_nbits > 0) {
Packit b00eeb
		display = g_strdup_printf ("%u", key_nbits);
Packit b00eeb
		_gcr_display_view_append_value (view, renderer, _("Key Size"), display, FALSE);
Packit b00eeb
		g_free (display);
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	value = egg_asn1x_get_element_raw (subject_public_key);
Packit b00eeb
	raw = gcr_fingerprint_from_subject_public_key_info (g_bytes_get_data (value, NULL),
Packit b00eeb
	                                                    g_bytes_get_size (value),
Packit b00eeb
	                                                    G_CHECKSUM_SHA1, &n_raw);
Packit b00eeb
	_gcr_display_view_append_hex (view, renderer, _("Key SHA1 Fingerprint"), raw, n_raw);
Packit b00eeb
	g_bytes_unref (value);
Packit b00eeb
	g_free (raw);
Packit b00eeb
Packit b00eeb
	value = egg_asn1x_get_bits_as_raw (egg_asn1x_node (subject_public_key, "subjectPublicKey", NULL), &bits);
Packit b00eeb
	_gcr_display_view_append_hex (view, renderer, _("Public Key"),
Packit b00eeb
	                              g_bytes_get_data (value, NULL), bits / 8);
Packit b00eeb
	g_bytes_unref (value);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
void
Packit b00eeb
_gcr_certificate_renderer_append_signature (GcrRenderer *renderer,
Packit b00eeb
                                            GcrDisplayView *view,
Packit b00eeb
                                            GNode *asn)
Packit b00eeb
{
Packit b00eeb
	const gchar *text;
Packit b00eeb
	GBytes *value;
Packit b00eeb
	GQuark oid;
Packit b00eeb
	guint bits;
Packit b00eeb
Packit b00eeb
	oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "signatureAlgorithm", "algorithm", NULL));
Packit b00eeb
	text = egg_oid_get_description (oid);
Packit b00eeb
	_gcr_display_view_append_value (view, renderer, _("Signature Algorithm"), text, FALSE);
Packit b00eeb
Packit b00eeb
	value = egg_asn1x_get_element_raw (egg_asn1x_node (asn, "signatureAlgorithm", "parameters", NULL));
Packit b00eeb
	if (value) {
Packit b00eeb
		_gcr_display_view_append_hex (view, renderer, _("Signature Parameters"),
Packit b00eeb
		                              g_bytes_get_data (value, NULL),
Packit b00eeb
		                              g_bytes_get_size (value));
Packit b00eeb
		g_bytes_unref (value);
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	value = egg_asn1x_get_bits_as_raw (egg_asn1x_node (asn, "signature", NULL), &bits);
Packit b00eeb
	_gcr_display_view_append_hex (view, renderer, _("Signature"),
Packit b00eeb
	                              g_bytes_get_data (value, NULL), bits / 8);
Packit b00eeb
	g_bytes_unref (value);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
void
Packit b00eeb
_gcr_certificate_renderer_append_extension (GcrRenderer *renderer,
Packit b00eeb
                                            GcrDisplayView *view,
Packit b00eeb
                                            GNode *node)
Packit b00eeb
{
Packit b00eeb
	GQuark oid;
Packit b00eeb
	GBytes *value;
Packit b00eeb
	gboolean critical;
Packit b00eeb
	gboolean ret = FALSE;
Packit b00eeb
Packit b00eeb
	/* Dig out the OID */
Packit b00eeb
	oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (node, "extnID", NULL));
Packit b00eeb
	g_return_if_fail (oid);
Packit b00eeb
Packit b00eeb
	/* Extension value */
Packit b00eeb
	value = egg_asn1x_get_string_as_bytes (egg_asn1x_node (node, "extnValue", NULL));
Packit b00eeb
Packit b00eeb
	/* The custom parsers */
Packit b00eeb
	if (oid == GCR_OID_BASIC_CONSTRAINTS)
Packit b00eeb
		ret = append_extension_basic_constraints (renderer, view, value);
Packit b00eeb
	else if (oid == GCR_OID_EXTENDED_KEY_USAGE)
Packit b00eeb
		ret = append_extension_extended_key_usage (renderer, view, value);
Packit b00eeb
	else if (oid == GCR_OID_SUBJECT_KEY_IDENTIFIER)
Packit b00eeb
		ret = append_extension_subject_key_identifier (renderer, view, value);
Packit b00eeb
	else if (oid == GCR_OID_KEY_USAGE)
Packit b00eeb
		ret = append_extension_key_usage (renderer, view, value);
Packit b00eeb
	else if (oid == GCR_OID_SUBJECT_ALT_NAME)
Packit b00eeb
		ret = append_extension_subject_alt_name (renderer, view, value);
Packit b00eeb
Packit b00eeb
	/* Otherwise the default raw display */
Packit b00eeb
	if (ret == FALSE)
Packit b00eeb
		ret = append_extension_hex (renderer, view, oid,
Packit b00eeb
		                            g_bytes_get_data (value, NULL),
Packit b00eeb
		                            g_bytes_get_size (value));
Packit b00eeb
Packit b00eeb
	/* Critical */
Packit b00eeb
	if (ret == TRUE && egg_asn1x_get_boolean (egg_asn1x_node (node, "critical", NULL), &critical)) {
Packit b00eeb
		_gcr_display_view_append_value (view, renderer, _("Critical"),
Packit b00eeb
		                                critical ? _("Yes") : _("No"), FALSE);
Packit b00eeb
	}
Packit b00eeb
}