2 * Copyright (C) 2010 Stefan Walter
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as
6 * published by the Free Software Foundation; either version 2.1 of
7 * the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
22 #include "gcr-certificate.h"
23 #include "gcr-certificate-exporter.h"
24 #include "gcr-certificate-extensions.h"
25 #include "gcr-certificate-renderer.h"
26 #include "gcr-display-view.h"
27 #include "gcr-fingerprint.h"
28 #include "gcr-icons.h"
30 #include "gcr-simple-certificate.h"
31 #include "gcr-renderer.h"
33 #include "egg/egg-asn1x.h"
34 #include "egg/egg-asn1-defs.h"
35 #include "egg/egg-dn.h"
36 #include "egg/egg-oid.h"
37 #include "egg/egg-hex.h"
42 #include <glib/gi18n-lib.h>
45 * GcrCertificateRenderer:
47 * An implementation of #GcrRenderer which renders certificates.
51 * GcrCertificateRendererClass:
52 * @parent_class: The parent class.
54 * The class for #GcrCertificateRenderer.
64 struct _GcrCertificateRendererPrivate {
65 GcrCertificate *opt_cert;
66 GckAttributes *opt_attrs;
71 static void gcr_renderer_iface_init (GcrRendererIface *iface);
72 static void gcr_renderer_certificate_iface_init (GcrCertificateIface *iface);
74 G_DEFINE_TYPE_WITH_CODE (GcrCertificateRenderer, gcr_certificate_renderer, G_TYPE_OBJECT,
75 G_IMPLEMENT_INTERFACE (GCR_TYPE_RENDERER, gcr_renderer_iface_init);
76 GCR_CERTIFICATE_MIXIN_IMPLEMENT_COMPARABLE ();
77 G_IMPLEMENT_INTERFACE (GCR_TYPE_CERTIFICATE, gcr_renderer_certificate_iface_init);
80 /* -----------------------------------------------------------------------------
85 calculate_label (GcrCertificateRenderer *self)
90 return g_strdup (self->pv->label);
92 if (self->pv->opt_attrs) {
93 if (gck_attributes_find_string (self->pv->opt_attrs, CKA_LABEL, &label))
97 label = gcr_certificate_get_subject_cn (GCR_CERTIFICATE (self));
101 return g_strdup (_("Certificate"));
105 append_extension_basic_constraints (GcrCertificateRenderer *self, GcrDisplayView *view,
106 gconstpointer data, gsize n_data)
108 GcrRenderer *renderer = GCR_RENDERER (self);
109 gboolean is_ca = FALSE;
113 if (!_gcr_certificate_extension_basic_constraints (data, n_data, &is_ca, &path_len))
116 _gcr_display_view_append_heading (view, renderer, _("Basic Constraints"));
118 _gcr_display_view_append_value (view, renderer, _("Certificate Authority"),
119 is_ca ? _("Yes") : _("No"), FALSE);
121 number = g_strdup_printf ("%d", path_len);
122 _gcr_display_view_append_value (view, renderer, _("Max Path Length"),
123 path_len < 0 ? _("Unlimited") : number, FALSE);
130 append_extension_extended_key_usage (GcrCertificateRenderer *self, GcrDisplayView *view,
131 gconstpointer data, gsize n_data)
133 GcrRenderer *renderer = GCR_RENDERER (self);
138 oids = _gcr_certificate_extension_extended_key_usage (data, n_data);
142 _gcr_display_view_append_heading (view, renderer, _("Extended Key Usage"));
144 text = g_string_new ("");
145 for (i = 0; oids[i] != 0; i++) {
147 g_string_append_unichar (text, GCR_DISPLAY_VIEW_LINE_BREAK);
148 g_string_append (text, egg_oid_get_description (oids[i]));
153 _gcr_display_view_append_value (view, renderer, _("Allowed Purposes"),
156 g_string_free (text, TRUE);
162 append_extension_subject_key_identifier (GcrCertificateRenderer *self, GcrDisplayView *view,
163 gconstpointer data, gsize n_data)
165 GcrRenderer *renderer = GCR_RENDERER (self);
169 keyid = _gcr_certificate_extension_subject_key_identifier (data, n_data, &n_keyid);
173 _gcr_display_view_append_heading (view, renderer, _("Subject Key Identifier"));
174 _gcr_display_view_append_hex (view, renderer, _("Key Identifier"), keyid, n_keyid);
181 static const struct {
183 const gchar *description;
184 } usage_descriptions[] = {
185 { GCR_KEY_USAGE_DIGITAL_SIGNATURE, N_("Digital signature") },
186 { GCR_KEY_USAGE_KEY_ENCIPHERMENT, N_("Key encipherment") },
187 { GCR_KEY_USAGE_DATA_ENCIPHERMENT, N_("Data encipherment") },
188 { GCR_KEY_USAGE_KEY_AGREEMENT, N_("Key agreement") },
189 { GCR_KEY_USAGE_KEY_CERT_SIGN, N_("Certificate signature") },
190 { GCR_KEY_USAGE_CRL_SIGN, N_("Revocation list signature") }
194 append_extension_key_usage (GcrCertificateRenderer *self, GcrDisplayView *view,
195 gconstpointer data, gsize n_data)
197 GcrRenderer *renderer = GCR_RENDERER (self);
202 if (!_gcr_certificate_extension_key_usage (data, n_data, &key_usage))
205 text = g_string_new ("");
207 for (i = 0; i < G_N_ELEMENTS (usage_descriptions); i++) {
208 if (key_usage & usage_descriptions[i].usage) {
210 g_string_append_unichar (text, GCR_DISPLAY_VIEW_LINE_BREAK);
211 g_string_append (text, gettext (usage_descriptions[i].description));
215 _gcr_display_view_append_heading (view, renderer, _("Key Usage"));
216 _gcr_display_view_append_value (view, renderer, _("Usages"), text->str, FALSE);
218 g_string_free (text, TRUE);
224 append_extension_subject_alt_name (GcrCertificateRenderer *self, GcrDisplayView *view,
225 gconstpointer data, gsize n_data)
227 GcrRenderer *renderer = GCR_RENDERER (self);
228 GArray *general_names;
229 GcrGeneralName *general;
232 general_names = _gcr_certificate_extension_subject_alt_name (data, n_data);
233 if (general_names == NULL)
236 _gcr_display_view_append_heading (view, renderer, _("Subject Alternative Names"));
238 for (i = 0; i < general_names->len; i++) {
239 general = &g_array_index (general_names, GcrGeneralName, i);
240 if (general->display == NULL)
241 _gcr_display_view_append_hex (view, renderer, general->description,
242 general->raw, general->n_raw);
244 _gcr_display_view_append_value (view, renderer, general->description,
245 general->display, FALSE);
248 _gcr_general_names_free (general_names);
255 append_extension_hex (GcrCertificateRenderer *self, GcrDisplayView *view,
256 GQuark oid, gconstpointer data, gsize n_data)
258 GcrRenderer *renderer = GCR_RENDERER (self);
261 _gcr_display_view_append_heading (view, renderer, _("Extension"));
264 text = egg_oid_get_description (oid);
265 _gcr_display_view_append_value (view, renderer, _("Identifier"), text, FALSE);
266 _gcr_display_view_append_hex (view, renderer, _("Value"), data, n_data);
272 append_extension (GcrCertificateRenderer *self, GcrDisplayView *view,
273 GNode *asn, const guchar *data, gsize n_data, gint index)
275 GcrRenderer *renderer = GCR_RENDERER (self);
281 gboolean ret = FALSE;
283 /* Make sure it is present */
284 node = egg_asn1x_node (asn, "tbsCertificate", "extensions", index, NULL);
288 /* Dig out the OID */
289 oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (node, "extnID", NULL));
290 g_return_val_if_fail (oid, FALSE);
292 /* Extension value */
293 value = egg_asn1x_get_raw_value (egg_asn1x_node (node, "extnValue", NULL), &n_value);
295 /* The custom parsers */
296 if (oid == GCR_OID_BASIC_CONSTRAINTS)
297 ret = append_extension_basic_constraints (self, view, value, n_value);
298 else if (oid == GCR_OID_EXTENDED_KEY_USAGE)
299 ret = append_extension_extended_key_usage (self, view, value, n_value);
300 else if (oid == GCR_OID_SUBJECT_KEY_IDENTIFIER)
301 ret = append_extension_subject_key_identifier (self, view, value, n_value);
302 else if (oid == GCR_OID_KEY_USAGE)
303 ret = append_extension_key_usage (self, view, value, n_value);
304 else if (oid == GCR_OID_SUBJECT_ALT_NAME)
305 ret = append_extension_subject_alt_name (self, view, value, n_value);
307 /* Otherwise the default raw display */
309 ret = append_extension_hex (self, view, oid, value, n_value);
312 if (ret == TRUE && egg_asn1x_get_boolean (egg_asn1x_node (node, "critical", NULL), &critical)) {
313 _gcr_display_view_append_value (view, renderer, _("Critical"),
314 critical ? _("Yes") : _("No"), FALSE);
320 typedef struct _on_parsed_dn_args {
321 GcrCertificateRenderer *renderer;
322 GcrDisplayView *view;
326 on_parsed_dn_part (guint index, GQuark oid, const guchar *value,
327 gsize n_value, gpointer user_data)
329 GcrCertificateRenderer *self = ((on_parsed_dn_args*)user_data)->renderer;
330 GcrDisplayView *view = ((on_parsed_dn_args*)user_data)->view;
336 g_return_if_fail (GCR_IS_CERTIFICATE_RENDERER (self));
338 attr = egg_oid_get_name (oid);
339 desc = egg_oid_get_description (oid);
341 /* Combine them into something sane */
343 if (strcmp (attr, desc) == 0)
344 field = g_strdup (attr);
346 field = g_strdup_printf ("%s (%s)", attr, desc);
347 } else if (!attr && !desc) {
348 field = g_strdup ("");
350 field = g_strdup (attr);
352 field = g_strdup (desc);
354 g_assert_not_reached ();
357 display = egg_dn_print_value (oid, value, n_value);
359 display = g_strdup ("");
361 _gcr_display_view_append_value (view, GCR_RENDERER (self), field, display, FALSE);
367 on_delete_unref_dialog (GtkWidget *widget, GdkEvent *event, gpointer data)
369 g_object_unref (widget);
374 on_export_completed (GObject *source, GAsyncResult *result, gpointer user_data)
376 GtkWindow *parent = GTK_WINDOW (user_data);
377 GcrCertificateExporter *exporter = GCR_CERTIFICATE_EXPORTER (source);
378 GError *error = NULL;
381 if (!_gcr_certificate_exporter_export_finish (exporter, result, &error)) {
382 if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
383 dialog = gtk_message_dialog_new_with_markup (parent,
384 GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR,
385 GTK_BUTTONS_OK, "<big>%s</big>\n\n%s",
386 _("Couldn't export the certificate."),
388 gtk_widget_show (dialog);
389 g_signal_connect (dialog, "delete-event",
390 G_CALLBACK (on_delete_unref_dialog), NULL);
394 /* Matches ref in on_certificate_export */
396 g_object_unref (parent);
400 on_certificate_export (GtkMenuItem *menuitem, gpointer user_data)
402 GcrCertificateRenderer *self = GCR_CERTIFICATE_RENDERER (user_data);
403 GcrCertificateExporter *exporter;
407 label = calculate_label (self);
409 parent = gtk_widget_get_toplevel (GTK_WIDGET (menuitem));
410 if (parent && !GTK_IS_WINDOW (parent))
413 exporter = _gcr_certificate_exporter_new (GCR_CERTIFICATE (self), label,
414 GTK_WINDOW (parent));
418 _gcr_certificate_exporter_export_async (exporter, NULL, on_export_completed,
419 parent ? g_object_ref (parent) : NULL);
422 /* -----------------------------------------------------------------------------
427 gcr_certificate_renderer_init (GcrCertificateRenderer *self)
429 self->pv = (G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_CERTIFICATE_RENDERER, GcrCertificateRendererPrivate));
433 gcr_certificate_renderer_dispose (GObject *obj)
435 GcrCertificateRenderer *self = GCR_CERTIFICATE_RENDERER (obj);
437 if (self->pv->opt_cert)
438 g_object_unref (self->pv->opt_cert);
439 self->pv->opt_cert = NULL;
441 G_OBJECT_CLASS (gcr_certificate_renderer_parent_class)->dispose (obj);
445 gcr_certificate_renderer_finalize (GObject *obj)
447 GcrCertificateRenderer *self = GCR_CERTIFICATE_RENDERER (obj);
449 g_assert (!self->pv->opt_cert);
451 if (self->pv->opt_attrs)
452 gck_attributes_unref (self->pv->opt_attrs);
453 self->pv->opt_attrs = NULL;
455 g_free (self->pv->label);
456 self->pv->label = NULL;
458 G_OBJECT_CLASS (gcr_certificate_renderer_parent_class)->finalize (obj);
462 gcr_certificate_renderer_set_property (GObject *obj, guint prop_id, const GValue *value,
465 GcrCertificateRenderer *self = GCR_CERTIFICATE_RENDERER (obj);
468 case PROP_CERTIFICATE:
469 gcr_certificate_renderer_set_certificate (self, g_value_get_object (value));
472 g_free (self->pv->label);
473 self->pv->label = g_value_dup_string (value);
474 g_object_notify (obj, "label");
475 gcr_renderer_emit_data_changed (GCR_RENDERER (self));
477 case PROP_ATTRIBUTES:
478 gcr_certificate_renderer_set_attributes (self, g_value_get_boxed (value));
481 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
487 gcr_certificate_renderer_get_property (GObject *obj, guint prop_id, GValue *value,
490 GcrCertificateRenderer *self = GCR_CERTIFICATE_RENDERER (obj);
493 case PROP_CERTIFICATE:
494 g_value_set_object (value, self->pv->opt_cert);
497 g_value_take_string (value, calculate_label (self));
499 case PROP_ATTRIBUTES:
500 g_value_set_boxed (value, self->pv->opt_attrs);
503 gcr_certificate_mixin_get_property (obj, prop_id, value, pspec);
509 gcr_certificate_renderer_class_init (GcrCertificateRendererClass *klass)
511 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
512 GckAttributes *registered;
516 gcr_certificate_renderer_parent_class = g_type_class_peek_parent (klass);
517 g_type_class_add_private (klass, sizeof (GcrCertificateRendererPrivate));
519 gobject_class->dispose = gcr_certificate_renderer_dispose;
520 gobject_class->finalize = gcr_certificate_renderer_finalize;
521 gobject_class->set_property = gcr_certificate_renderer_set_property;
522 gobject_class->get_property = gcr_certificate_renderer_get_property;
525 * GcrCertificateRenderer:certificate:
527 * The certificate to display. May be %NULL.
529 g_object_class_install_property (gobject_class, PROP_CERTIFICATE,
530 g_param_spec_object ("certificate", "Certificate", "Certificate to display.",
531 GCR_TYPE_CERTIFICATE, G_PARAM_READWRITE));
534 * GcrCertificateRenderer:attributes:
536 * The certificate attributes to display. One of the attributes must be
537 * a CKA_VALUE type attribute which contains a DER encoded certificate.
539 g_object_class_install_property (gobject_class, PROP_ATTRIBUTES,
540 g_param_spec_boxed ("attributes", "Attributes", "Certificate pkcs11 attributes",
541 GCK_TYPE_ATTRIBUTES, G_PARAM_READWRITE));
544 * GcrCertificateRenderer:label:
546 * The label to display.
548 g_object_class_install_property (gobject_class, PROP_LABEL,
549 g_param_spec_string ("label", "Label", "Certificate Label",
550 "", G_PARAM_READWRITE));
552 gcr_certificate_mixin_class_init (gobject_class);
554 /* Register this as a renderer which can be loaded */
555 registered = gck_attributes_new ();
556 gck_attributes_add_ulong (registered, CKA_CLASS, CKO_CERTIFICATE);
557 gcr_renderer_register (GCR_TYPE_CERTIFICATE_RENDERER, registered);
558 gck_attributes_unref (registered);
562 gcr_certificate_renderer_render (GcrRenderer *renderer, GcrViewer *viewer)
564 GcrCertificateRenderer *self;
565 gconstpointer data, value;
566 gsize n_data, n_value, n_raw;
567 GcrDisplayView *view;
568 on_parsed_dn_args args;
570 GcrCertificate *cert;
572 gconstpointer number;
581 self = GCR_CERTIFICATE_RENDERER (renderer);
583 if (GCR_IS_DISPLAY_VIEW (viewer)) {
584 view = GCR_DISPLAY_VIEW (viewer);
587 g_warning ("GcrCertificateRenderer only works with internal specific "
588 "GcrViewer returned by gcr_viewer_new().");
592 _gcr_display_view_begin (view, renderer);
593 cert = GCR_CERTIFICATE (self);
595 data = gcr_certificate_get_der_data (cert, &n_data);
597 _gcr_display_view_end (view, renderer);
601 icon = gcr_certificate_get_icon (cert);
602 _gcr_display_view_set_icon (view, GCR_RENDERER (self), icon);
603 g_object_unref (icon);
605 asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", data, n_data);
606 g_return_if_fail (asn);
608 display = calculate_label (self);
609 _gcr_display_view_append_title (view, renderer, display);
612 display = egg_dn_read_part (egg_asn1x_node (asn, "tbsCertificate", "subject", "rdnSequence", NULL), "CN");
613 _gcr_display_view_append_content (view, renderer, _("Identity"), display);
616 display = egg_dn_read_part (egg_asn1x_node (asn, "tbsCertificate", "issuer", "rdnSequence", NULL), "CN");
617 _gcr_display_view_append_content (view, renderer, _("Verified by"), display);
620 if (egg_asn1x_get_time_as_date (egg_asn1x_node (asn, "tbsCertificate", "validity", "notAfter", NULL), &date)) {
621 display = g_malloc0 (128);
622 if (!g_date_strftime (display, 128, "%x", &date))
623 g_return_if_reached ();
624 _gcr_display_view_append_content (view, renderer, _("Expires"), display);
628 _gcr_display_view_start_details (view, renderer);
630 args.renderer = self;
634 _gcr_display_view_append_heading (view, renderer, _("Subject Name"));
635 egg_dn_parse (egg_asn1x_node (asn, "tbsCertificate", "subject", "rdnSequence", NULL), on_parsed_dn_part, &args);
638 _gcr_display_view_append_heading (view, renderer, _("Issuer Name"));
639 egg_dn_parse (egg_asn1x_node (asn, "tbsCertificate", "issuer", "rdnSequence", NULL), on_parsed_dn_part, &args);
641 /* The Issued Parameters */
642 _gcr_display_view_append_heading (view, renderer, _("Issued Certificate"));
644 if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "tbsCertificate", "version", NULL), &version))
645 g_return_if_reached ();
646 display = g_strdup_printf ("%lu", version + 1);
647 _gcr_display_view_append_value (view, renderer, _("Version"), display, FALSE);
650 number = egg_asn1x_get_integer_as_raw (egg_asn1x_node (asn, "tbsCertificate", "serialNumber", NULL), &n_raw);
651 g_return_if_fail (number != NULL);
652 _gcr_display_view_append_hex (view, renderer, _("Serial Number"), number, n_raw);
654 display = g_malloc0 (128);
655 if (egg_asn1x_get_time_as_date (egg_asn1x_node (asn, "tbsCertificate", "validity", "notBefore", NULL), &date)) {
656 if (!g_date_strftime (display, 128, "%Y-%m-%d", &date))
657 g_return_if_reached ();
658 _gcr_display_view_append_value (view, renderer, _("Not Valid Before"), display, FALSE);
660 if (egg_asn1x_get_time_as_date (egg_asn1x_node (asn, "tbsCertificate", "validity", "notAfter", NULL), &date)) {
661 if (!g_date_strftime (display, 128, "%Y-%m-%d", &date))
662 g_return_if_reached ();
663 _gcr_display_view_append_value (view, renderer, _("Not Valid After"), display, FALSE);
668 _gcr_display_view_append_heading (view, renderer, _("Certificate Fingerprints"));
670 _gcr_display_view_append_fingerprint (view, renderer, data, n_data, "SHA1", G_CHECKSUM_SHA1);
671 _gcr_display_view_append_fingerprint (view, renderer, data, n_data, "MD5", G_CHECKSUM_MD5);
674 _gcr_display_view_append_heading (view, renderer, _("Signature"));
676 oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "signatureAlgorithm", "algorithm", NULL));
677 text = egg_oid_get_description (oid);
678 _gcr_display_view_append_value (view, renderer, _("Signature Algorithm"), text, FALSE);
680 value = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "signatureAlgorithm", "parameters", NULL), &n_value);
681 if (value && n_value)
682 _gcr_display_view_append_hex (view, renderer, _("Signature Parameters"), value, n_value);
684 raw = egg_asn1x_get_bits_as_raw (egg_asn1x_node (asn, "signature", NULL), NULL, &bits);
685 g_return_if_fail (raw);
686 _gcr_display_view_append_hex (view, renderer, _("Signature"), raw, bits / 8);
689 /* Public Key Info */
690 _gcr_display_view_append_heading (view, renderer, _("Public Key Info"));
692 oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "tbsCertificate", "subjectPublicKeyInfo",
693 "algorithm", "algorithm", NULL));
694 text = egg_oid_get_description (oid);
695 _gcr_display_view_append_value (view, renderer, _("Key Algorithm"), text, FALSE);
697 value = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "tbsCertificate", "subjectPublicKeyInfo",
698 "algorithm", "parameters", NULL), &n_value);
699 if (value && n_value)
700 _gcr_display_view_append_hex (view, renderer, _("Key Parameters"), value, n_value);
702 bits = gcr_certificate_get_key_size (cert);
704 display = g_strdup_printf ("%u", bits);
705 _gcr_display_view_append_value (view, renderer, _("Key Size"), display, FALSE);
709 value = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "tbsCertificate",
710 "subjectPublicKeyInfo", NULL), &n_value);
711 raw = gcr_fingerprint_from_subject_public_key_info (value, n_value, G_CHECKSUM_SHA1, &n_raw);
712 _gcr_display_view_append_hex (view, renderer, _("Key SHA1 Fingerprint"), raw, n_raw);
715 raw = egg_asn1x_get_bits_as_raw (egg_asn1x_node (asn, "tbsCertificate", "subjectPublicKeyInfo",
716 "subjectPublicKey", NULL), NULL, &bits);
717 g_return_if_fail (raw);
718 _gcr_display_view_append_hex (view, renderer, _("Public Key"), raw, bits / 8);
722 for (index = 1; TRUE; ++index) {
723 if (!append_extension (self, view, asn, data, n_data, index))
727 egg_asn1x_destroy (asn);
728 _gcr_display_view_end (view, renderer);
732 gcr_certificate_renderer_populate_popup (GcrRenderer *self, GcrViewer *viewer,
737 item = gtk_separator_menu_item_new ();
738 gtk_widget_show (item);
739 gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
741 item = gtk_menu_item_new_with_label ("Export Certificate...");
742 gtk_widget_show (item);
743 g_signal_connect_data (item, "activate", G_CALLBACK (on_certificate_export),
744 g_object_ref (self), (GClosureNotify)g_object_unref, 0);
745 gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
749 gcr_renderer_iface_init (GcrRendererIface *iface)
751 iface->populate_popup = gcr_certificate_renderer_populate_popup;
752 iface->render_view = gcr_certificate_renderer_render;
755 static const guchar *
756 gcr_certificate_renderer_get_der_data (GcrCertificate *cert,
759 GcrCertificateRenderer *self = GCR_CERTIFICATE_RENDERER (cert);
764 if (self->pv->opt_cert)
765 return gcr_certificate_get_der_data (self->pv->opt_cert, n_data);
767 if (self->pv->opt_attrs) {
768 attr = gck_attributes_find (self->pv->opt_attrs, CKA_VALUE);
769 g_return_val_if_fail (attr, NULL);
770 *n_data = attr->length;
778 gcr_renderer_certificate_iface_init (GcrCertificateIface *iface)
780 iface->get_der_data = gcr_certificate_renderer_get_der_data;
783 /* -----------------------------------------------------------------------------
788 * gcr_certificate_renderer_new:
789 * @certificate: The certificate to display
791 * Create a new certificate renderer to display the certificate.
793 * Returns: (transfer full): a newly allocated #GcrCertificateRenderer, which
794 * should be released with g_object_unref()
796 GcrCertificateRenderer *
797 gcr_certificate_renderer_new (GcrCertificate *certificate)
799 return g_object_new (GCR_TYPE_CERTIFICATE_RENDERER, "certificate", certificate, NULL);
803 * gcr_certificate_renderer_new_for_attributes:
804 * @label: (allow-none): the label to display
805 * @attrs: The attributes to display
807 * Create a new certificate renderer to display the label and attributes. One
808 * of the attributes should be a CKA_VALUE type attribute containing a DER
809 * encoded certificate.
811 * Returns: (transfer full): a newly allocated #GcrCertificateRenderer, which
812 * should be released with g_object_unref()
814 GcrCertificateRenderer *
815 gcr_certificate_renderer_new_for_attributes (const gchar *label, struct _GckAttributes *attrs)
817 return g_object_new (GCR_TYPE_CERTIFICATE_RENDERER, "label", label, "attributes", attrs, NULL);
821 * gcr_certificate_renderer_get_certificate:
822 * @self: The renderer
824 * Get the certificate displayed in the renderer. If no certificate was
825 * explicitly set, then the renderer will return itself since it acts as
826 * a valid certificate.
828 * Returns: (transfer none): The certificate, owned by the renderer.
831 gcr_certificate_renderer_get_certificate (GcrCertificateRenderer *self)
833 g_return_val_if_fail (GCR_IS_CERTIFICATE_RENDERER (self), NULL);
834 if (self->pv->opt_cert)
835 return self->pv->opt_cert;
836 return GCR_CERTIFICATE (self);
840 * gcr_certificate_renderer_set_certificate:
841 * @self: The renderer
842 * @certificate: (allow-none): the certificate to display
844 * Set a certificate to display in the renderer.
847 gcr_certificate_renderer_set_certificate (GcrCertificateRenderer *self, GcrCertificate *certificate)
849 g_return_if_fail (GCR_IS_CERTIFICATE_RENDERER (self));
851 if (self->pv->opt_cert)
852 g_object_unref (self->pv->opt_cert);
853 self->pv->opt_cert = certificate;
854 if (self->pv->opt_cert)
855 g_object_ref (self->pv->opt_cert);
857 if (self->pv->opt_attrs) {
858 gck_attributes_unref (self->pv->opt_attrs);
859 self->pv->opt_attrs = NULL;
862 gcr_renderer_emit_data_changed (GCR_RENDERER (self));
863 g_object_notify (G_OBJECT (self), "certificate");
867 * gcr_certificate_renderer_get_attributes:
868 * @self: The renderer
870 * Get the PKCS\#11 attributes, if any, set for this renderer to display.
872 * Returns: (allow-none) (transfer none): the attributes, owned by the renderer
875 gcr_certificate_renderer_get_attributes (GcrCertificateRenderer *self)
877 g_return_val_if_fail (GCR_IS_CERTIFICATE_RENDERER (self), NULL);
878 return self->pv->opt_attrs;
882 * gcr_certificate_renderer_set_attributes:
883 * @self: The renderer
884 * @attrs: (allow-none): attributes to set
886 * Set the PKCS\#11 attributes for this renderer to display. One of the attributes
887 * should be a CKA_VALUE type attribute containing a DER encoded certificate.
890 gcr_certificate_renderer_set_attributes (GcrCertificateRenderer *self, GckAttributes *attrs)
892 g_return_if_fail (GCR_IS_CERTIFICATE_RENDERER (self));
894 gck_attributes_unref (self->pv->opt_attrs);
895 self->pv->opt_attrs = attrs;
897 if (self->pv->opt_attrs)
898 gck_attributes_ref (self->pv->opt_attrs);
900 if (self->pv->opt_cert) {
901 g_object_unref (self->pv->opt_cert);
902 g_object_notify (G_OBJECT (self), "certificate");
903 self->pv->opt_cert = NULL;
906 gcr_renderer_emit_data_changed (GCR_RENDERER (self));
907 g_object_notify (G_OBJECT (self), "attributes");