Blame ui/gcr-certificate-request-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-oids.h"
Packit b00eeb
#include "gcr/gcr-subject-public-key.h"
Packit b00eeb
Packit b00eeb
#include "gcr-certificate-renderer-private.h"
Packit b00eeb
#include "gcr-certificate-request-renderer.h"
Packit b00eeb
#include "gcr-display-view.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
Packit b00eeb
#include "gck/gck.h"
Packit b00eeb
Packit b00eeb
#include <glib/gi18n-lib.h>
Packit b00eeb
Packit b00eeb
/**
Packit b00eeb
 * GcrCertificateRequestRenderer:
Packit b00eeb
 *
Packit b00eeb
 * An implementation of #GcrRenderer which renders certificate requests
Packit b00eeb
 */
Packit b00eeb
Packit b00eeb
/**
Packit b00eeb
 * GcrCertificateRequestRendererClass:
Packit b00eeb
 * @parent_class: The parent class
Packit b00eeb
 *
Packit b00eeb
 * The class for #GcrCertificateRequestRenderer
Packit b00eeb
 */
Packit b00eeb
Packit b00eeb
enum {
Packit b00eeb
	PROP_0,
Packit b00eeb
	PROP_LABEL,
Packit b00eeb
	PROP_ATTRIBUTES
Packit b00eeb
};
Packit b00eeb
Packit b00eeb
struct _GcrCertificateRequestRendererPrivate {
Packit b00eeb
	GckAttributes *attrs;
Packit b00eeb
	gchar *label;
Packit b00eeb
Packit b00eeb
	guint key_size;
Packit b00eeb
	gulong type;
Packit b00eeb
	GNode *asn;
Packit b00eeb
};
Packit b00eeb
Packit b00eeb
static void     _gcr_certificate_request_renderer_iface    (GcrRendererIface *iface);
Packit b00eeb
Packit b00eeb
G_DEFINE_TYPE_WITH_CODE (GcrCertificateRequestRenderer, _gcr_certificate_request_renderer, G_TYPE_OBJECT,
Packit b00eeb
	G_IMPLEMENT_INTERFACE (GCR_TYPE_RENDERER, _gcr_certificate_request_renderer_iface);
Packit b00eeb
);
Packit b00eeb
Packit b00eeb
static gchar*
Packit b00eeb
calculate_label (GcrCertificateRequestRenderer *self)
Packit b00eeb
{
Packit b00eeb
	gchar *label = NULL;
Packit b00eeb
Packit b00eeb
	if (self->pv->label)
Packit b00eeb
		return g_strdup (self->pv->label);
Packit b00eeb
Packit b00eeb
	if (self->pv->attrs) {
Packit b00eeb
		if (gck_attributes_find_string (self->pv->attrs, CKA_LABEL, &label))
Packit b00eeb
			return label;
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	if (self->pv->asn && self->pv->type == CKQ_GCR_PKCS10) {
Packit b00eeb
		label = egg_dn_read_part (egg_asn1x_node (self->pv->asn,
Packit b00eeb
		                                          "certificationRequestInfo",
Packit b00eeb
		                                          "subject",
Packit b00eeb
		                                          "rdnSequence",
Packit b00eeb
		                                          NULL), "CN");
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	if (label != NULL)
Packit b00eeb
		return label;
Packit b00eeb
Packit b00eeb
	return g_strdup (_("Certificate request"));
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
_gcr_certificate_request_renderer_init (GcrCertificateRequestRenderer *self)
Packit b00eeb
{
Packit b00eeb
	self->pv = (G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_CERTIFICATE_REQUEST_RENDERER,
Packit b00eeb
	                                         GcrCertificateRequestRendererPrivate));
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
_gcr_certificate_request_renderer_finalize (GObject *obj)
Packit b00eeb
{
Packit b00eeb
	GcrCertificateRequestRenderer *self = GCR_CERTIFICATE_REQUEST_RENDERER (obj);
Packit b00eeb
Packit b00eeb
	if (self->pv->attrs)
Packit b00eeb
		gck_attributes_unref (self->pv->attrs);
Packit b00eeb
	self->pv->attrs = NULL;
Packit b00eeb
Packit b00eeb
	g_free (self->pv->label);
Packit b00eeb
	self->pv->label = NULL;
Packit b00eeb
Packit b00eeb
	egg_asn1x_destroy (self->pv->asn);
Packit b00eeb
Packit b00eeb
	G_OBJECT_CLASS (_gcr_certificate_request_renderer_parent_class)->finalize (obj);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
_gcr_certificate_request_renderer_set_property (GObject *obj,
Packit b00eeb
                                            guint prop_id,
Packit b00eeb
                                            const GValue *value,
Packit b00eeb
                                            GParamSpec *pspec)
Packit b00eeb
{
Packit b00eeb
	GcrCertificateRequestRenderer *self = GCR_CERTIFICATE_REQUEST_RENDERER (obj);
Packit b00eeb
Packit b00eeb
	switch (prop_id) {
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
		_gcr_certificate_request_renderer_set_attributes (self, g_value_get_boxed (value));
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_request_renderer_get_property (GObject *obj,
Packit b00eeb
                                            guint prop_id,
Packit b00eeb
                                            GValue *value,
Packit b00eeb
                                            GParamSpec *pspec)
Packit b00eeb
{
Packit b00eeb
	GcrCertificateRequestRenderer *self = GCR_CERTIFICATE_REQUEST_RENDERER (obj);
Packit b00eeb
Packit b00eeb
	switch (prop_id) {
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->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_request_renderer_class_init (GcrCertificateRequestRendererClass *klass)
Packit b00eeb
{
Packit b00eeb
	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
Packit b00eeb
	GckBuilder builder = GCK_BUILDER_INIT;
Packit b00eeb
Packit b00eeb
	g_type_class_add_private (klass, sizeof (GcrCertificateRequestRendererPrivate));
Packit b00eeb
Packit b00eeb
	gobject_class->finalize = _gcr_certificate_request_renderer_finalize;
Packit b00eeb
	gobject_class->set_property = _gcr_certificate_request_renderer_set_property;
Packit b00eeb
	gobject_class->get_property = _gcr_certificate_request_renderer_get_property;
Packit b00eeb
Packit b00eeb
	/**
Packit b00eeb
	 * GcrCertificateRequestRenderer: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
	 * GcrCertificateRequestRenderer:label:
Packit b00eeb
	 *
Packit b00eeb
	 * The label to display.
Packit b00eeb
	 */
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
	/* Register this as a renderer which can be loaded */
Packit b00eeb
	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_GCR_CERTIFICATE_REQUEST);
Packit b00eeb
	gck_builder_add_ulong (&builder, CKA_GCR_CERTIFICATE_REQUEST_TYPE, CKQ_GCR_PKCS10);
Packit b00eeb
	gcr_renderer_register (GCR_TYPE_CERTIFICATE_REQUEST_RENDERER, gck_builder_end (&builder));
Packit b00eeb
Packit b00eeb
	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_GCR_CERTIFICATE_REQUEST);
Packit b00eeb
	gck_builder_add_ulong (&builder, CKA_GCR_CERTIFICATE_REQUEST_TYPE, CKQ_GCR_SPKAC);
Packit b00eeb
	gcr_renderer_register (GCR_TYPE_CERTIFICATE_REQUEST_RENDERER, gck_builder_end (&builder));
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static gboolean
Packit b00eeb
append_extension_request (GcrRenderer *renderer,
Packit b00eeb
                          GcrDisplayView *view,
Packit b00eeb
                          GNode *attribute)
Packit b00eeb
{
Packit b00eeb
	GBytes *value;
Packit b00eeb
	GNode *node;
Packit b00eeb
	GNode *asn;
Packit b00eeb
	guint i;
Packit b00eeb
Packit b00eeb
	node = egg_asn1x_node (attribute, "values", 1, NULL);
Packit b00eeb
	if (node == NULL)
Packit b00eeb
		return FALSE;
Packit b00eeb
Packit b00eeb
	value = egg_asn1x_get_element_raw (node);
Packit b00eeb
	asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "ExtensionRequest", value);
Packit b00eeb
	if (asn == NULL)
Packit b00eeb
		return FALSE;
Packit b00eeb
Packit b00eeb
	for (i = 1; TRUE; i++) {
Packit b00eeb
		node = egg_asn1x_node (asn, i, NULL);
Packit b00eeb
		if (node == NULL)
Packit b00eeb
			break;
Packit b00eeb
		_gcr_certificate_renderer_append_extension (renderer, view, node);
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	egg_asn1x_destroy (asn);
Packit b00eeb
	return TRUE;
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
append_attribute (GcrRenderer *renderer,
Packit b00eeb
                  GcrDisplayView *view,
Packit b00eeb
                  GNode *attribute)
Packit b00eeb
{
Packit b00eeb
	GQuark oid;
Packit b00eeb
	GBytes *value;
Packit b00eeb
	const gchar *text;
Packit b00eeb
	GNode *node;
Packit b00eeb
	gboolean ret = FALSE;
Packit b00eeb
	gint i;
Packit b00eeb
Packit b00eeb
	/* Dig out the OID */
Packit b00eeb
	oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (attribute, "type", NULL));
Packit b00eeb
	g_return_if_fail (oid);
Packit b00eeb
Packit b00eeb
	if (oid == GCR_OID_PKCS9_ATTRIBUTE_EXTENSION_REQ)
Packit b00eeb
		ret = append_extension_request (renderer, view, attribute);
Packit b00eeb
Packit b00eeb
	if (!ret) {
Packit b00eeb
		_gcr_display_view_append_heading (view, renderer, _("Attribute"));
Packit b00eeb
Packit b00eeb
		/* Extension type */
Packit b00eeb
		text = egg_oid_get_description (oid);
Packit b00eeb
		_gcr_display_view_append_value (view, renderer, _("Type"), text, FALSE);
Packit b00eeb
Packit b00eeb
		for (i = 1; TRUE; i++) {
Packit b00eeb
			node = egg_asn1x_node (attribute, "values", i, NULL);
Packit b00eeb
			if (node == NULL)
Packit b00eeb
				break;
Packit b00eeb
			value = egg_asn1x_get_element_raw (node);
Packit b00eeb
			_gcr_display_view_append_hex (view, renderer, _("Value"),
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
}
Packit b00eeb
Packit b00eeb
static guint
Packit b00eeb
ensure_key_size (GcrCertificateRequestRenderer *self,
Packit b00eeb
                 GNode *public_key)
Packit b00eeb
{
Packit b00eeb
	if (self->pv->key_size)
Packit b00eeb
		return self->pv->key_size;
Packit b00eeb
Packit b00eeb
	self->pv->key_size = _gcr_subject_public_key_calculate_size (public_key);
Packit b00eeb
	return self->pv->key_size;
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
render_pkcs10_certificate_req (GcrCertificateRequestRenderer *self,
Packit b00eeb
                               GcrDisplayView *view)
Packit b00eeb
{
Packit b00eeb
	GcrRenderer *renderer = GCR_RENDERER (self);
Packit b00eeb
	GNode *public_key;
Packit b00eeb
	GNode *attribute;
Packit b00eeb
	GNode *subject;
Packit b00eeb
	gchar *display;
Packit b00eeb
	gulong version;
Packit b00eeb
	guint bits;
Packit b00eeb
	guint i;
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
	_gcr_display_view_append_content (view, renderer, _("Certificate request"), NULL);
Packit b00eeb
Packit b00eeb
	subject = egg_asn1x_node (self->pv->asn, "certificationRequestInfo",
Packit b00eeb
	                          "subject", "rdnSequence", NULL);
Packit b00eeb
	display = egg_dn_read_part (subject, "CN");
Packit b00eeb
	_gcr_display_view_append_content (view, renderer, _("Identity"), display);
Packit b00eeb
	g_free (display);
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, subject);
Packit b00eeb
Packit b00eeb
	/* The certificate request type */
Packit b00eeb
	_gcr_display_view_append_heading (view, renderer, _("Certificate request"));
Packit b00eeb
	_gcr_display_view_append_value (view, renderer, _("Type"), "PKCS#10", FALSE);
Packit b00eeb
	if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (self->pv->asn,
Packit b00eeb
	                                                     "certificationRequestInfo",
Packit b00eeb
	                                                     "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
	_gcr_display_view_append_heading (view, renderer, _("Public Key Info"));
Packit b00eeb
	public_key = egg_asn1x_node (self->pv->asn, "certificationRequestInfo", "subjectPKInfo", NULL);
Packit b00eeb
	bits = ensure_key_size (self, public_key);
Packit b00eeb
	_gcr_certificate_renderer_append_subject_public_key (renderer, view,
Packit b00eeb
	                                                     bits, public_key);
Packit b00eeb
Packit b00eeb
	/* Attributes */
Packit b00eeb
	for (i = 1; TRUE; ++i) {
Packit b00eeb
		/* Make sure it is present */
Packit b00eeb
		attribute = egg_asn1x_node (self->pv->asn, "certificationRequestInfo", "attributes", i, NULL);
Packit b00eeb
		if (attribute == NULL)
Packit b00eeb
			break;
Packit b00eeb
		append_attribute (renderer, view, attribute);
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, self->pv->asn);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
render_spkac_certificate_req (GcrCertificateRequestRenderer *self,
Packit b00eeb
                              GcrDisplayView *view)
Packit b00eeb
{
Packit b00eeb
	GcrRenderer *renderer = GCR_RENDERER (self);
Packit b00eeb
	GNode *public_key;
Packit b00eeb
	gchar *display;
Packit b00eeb
	guint bits;
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
	_gcr_display_view_append_content (view, renderer, _("Certificate request"), NULL);
Packit b00eeb
Packit b00eeb
	_gcr_display_view_start_details (view, renderer);
Packit b00eeb
Packit b00eeb
	/* The certificate request type */
Packit b00eeb
	_gcr_display_view_append_heading (view, renderer, _("Certificate request"));
Packit b00eeb
	_gcr_display_view_append_value (view, renderer, _("Type"), "SPKAC", FALSE);
Packit b00eeb
Packit b00eeb
	display = egg_asn1x_get_string_as_utf8 (egg_asn1x_node (self->pv->asn, "publicKeyAndChallenge",
Packit b00eeb
	                                                        "challenge", NULL), NULL);
Packit b00eeb
	_gcr_display_view_append_value (view, renderer, _("Challenge"), display, FALSE);
Packit b00eeb
	g_free (display);
Packit b00eeb
Packit b00eeb
	_gcr_display_view_append_heading (view, renderer, _("Public Key Info"));
Packit b00eeb
	public_key = egg_asn1x_node (self->pv->asn, "publicKeyAndChallenge", "spki", NULL);
Packit b00eeb
	bits = ensure_key_size (self, public_key);
Packit b00eeb
	_gcr_certificate_renderer_append_subject_public_key (renderer, view,
Packit b00eeb
	                                                     bits, public_key);
Packit b00eeb
Packit b00eeb
	/* Signature */
Packit b00eeb
	_gcr_display_view_append_heading (view, renderer, _("Signature"));
Packit b00eeb
	_gcr_certificate_renderer_append_signature (renderer, view, self->pv->asn);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
gcr_certificate_request_renderer_render (GcrRenderer *renderer,
Packit b00eeb
                                     GcrViewer *viewer)
Packit b00eeb
{
Packit b00eeb
	GcrCertificateRequestRenderer *self;
Packit b00eeb
	GcrDisplayView *view;
Packit b00eeb
	GIcon *icon;
Packit b00eeb
Packit b00eeb
	self = GCR_CERTIFICATE_REQUEST_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 ("GcrCertificateRequestRenderer 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
Packit b00eeb
	icon = g_themed_icon_new ("dialog-question");
Packit b00eeb
	_gcr_display_view_set_icon (view, GCR_RENDERER (self), icon);
Packit b00eeb
	g_object_unref (icon);
Packit b00eeb
Packit b00eeb
	switch (self->pv->type) {
Packit b00eeb
	case CKQ_GCR_PKCS10:
Packit b00eeb
		render_pkcs10_certificate_req (self, view);
Packit b00eeb
		break;
Packit b00eeb
	case CKQ_GCR_SPKAC:
Packit b00eeb
		render_spkac_certificate_req (self, view);
Packit b00eeb
		break;
Packit b00eeb
	default:
Packit b00eeb
		g_warning ("unknown request type in GcrCertificateRequestRenderer");
Packit b00eeb
		break;
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	_gcr_display_view_end (view, renderer);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
_gcr_certificate_request_renderer_iface (GcrRendererIface *iface)
Packit b00eeb
{
Packit b00eeb
	iface->render_view = gcr_certificate_request_renderer_render;
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
/**
Packit b00eeb
 * gcr_certificate_request_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 request renderer to display the label and attributes.
Packit b00eeb
 * One of the attributes should be a CKA_VALUE type attribute containing a DER
Packit b00eeb
 * encoded PKCS\#10 certificate request or an SPKAC request.
Packit b00eeb
 *
Packit b00eeb
 * Returns: (transfer full): a newly allocated #GcrCertificateRequestRenderer, which
Packit b00eeb
 *          should be released with g_object_unref()
Packit b00eeb
 */
Packit b00eeb
GcrRenderer *
Packit b00eeb
_gcr_certificate_request_renderer_new_for_attributes (const gchar *label,
Packit b00eeb
                                                  GckAttributes *attrs)
Packit b00eeb
{
Packit b00eeb
	return g_object_new (GCR_TYPE_CERTIFICATE_REQUEST_RENDERER,
Packit b00eeb
	                     "label", label,
Packit b00eeb
	                     "attributes", attrs,
Packit b00eeb
	                     NULL);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
/**
Packit b00eeb
 * gcr_certificate_request_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
GckAttributes *
Packit b00eeb
_gcr_certificate_request_renderer_get_attributes (GcrCertificateRequestRenderer *self)
Packit b00eeb
{
Packit b00eeb
	g_return_val_if_fail (GCR_IS_CERTIFICATE_REQUEST_RENDERER (self), NULL);
Packit b00eeb
	return self->pv->attrs;
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
/**
Packit b00eeb
 * gcr_certificate_request_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 PKCS\#10
Packit b00eeb
 * certificate request or an SPKAC request.
Packit b00eeb
 */
Packit b00eeb
void
Packit b00eeb
_gcr_certificate_request_renderer_set_attributes (GcrCertificateRequestRenderer *self,
Packit b00eeb
                                              GckAttributes *attrs)
Packit b00eeb
{
Packit b00eeb
	const GckAttribute *value;
Packit b00eeb
	GNode *asn = NULL;
Packit b00eeb
	gulong type = 0;
Packit b00eeb
	GBytes *bytes;
Packit b00eeb
Packit b00eeb
	g_return_if_fail (GCR_IS_CERTIFICATE_REQUEST_RENDERER (self));
Packit b00eeb
Packit b00eeb
	if (attrs) {
Packit b00eeb
		value = gck_attributes_find (attrs, CKA_VALUE);
Packit b00eeb
		if (value == NULL) {
Packit b00eeb
			g_warning ("no CKA_VALUE found in attributes passed to "
Packit b00eeb
				   "GcrCertificateRequestRenderer attributes property");
Packit b00eeb
			return;
Packit b00eeb
		}
Packit b00eeb
Packit b00eeb
		bytes = g_bytes_new_with_free_func (value->value, value->length,
Packit b00eeb
		                                      gck_attributes_unref, gck_attributes_ref (attrs));
Packit b00eeb
Packit b00eeb
		asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-10-CertificationRequest", bytes);
Packit b00eeb
		if (asn != NULL) {
Packit b00eeb
			type = CKQ_GCR_PKCS10;
Packit b00eeb
		} else {
Packit b00eeb
			asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "SignedPublicKeyAndChallenge", bytes);
Packit b00eeb
			if (asn != NULL) {
Packit b00eeb
				type = CKQ_GCR_SPKAC;
Packit b00eeb
			} else {
Packit b00eeb
				g_warning ("the data contained in the CKA_VALUE attribute passed to "
Packit b00eeb
				           "GcrCertificateRequestRenderer was not valid DER encoded PKCS#10 "
Packit b00eeb
				           "or SPKAC");
Packit b00eeb
			}
Packit b00eeb
		}
Packit b00eeb
Packit b00eeb
		g_bytes_unref (bytes);
Packit b00eeb
Packit b00eeb
		if (type == 0)
Packit b00eeb
			return;
Packit b00eeb
Packit b00eeb
		gck_attributes_ref (attrs);
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	if (self->pv->attrs)
Packit b00eeb
		gck_attributes_unref (self->pv->attrs);
Packit b00eeb
	self->pv->attrs = attrs;
Packit b00eeb
	self->pv->asn = asn;
Packit b00eeb
	self->pv->type = type;
Packit b00eeb
	self->pv->key_size = 0; /* calculated later */
Packit b00eeb
Packit b00eeb
	gcr_renderer_emit_data_changed (GCR_RENDERER (self));
Packit b00eeb
	g_object_notify (G_OBJECT (self), "attributes");
Packit b00eeb
}