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-certificate-renderer-private.h"
27 #include "gcr-display-view.h"
28 #include "gcr-fingerprint.h"
29 #include "gcr-icons.h"
31 #include "gcr-simple-certificate.h"
32 #include "gcr-renderer.h"
34 #include "egg/egg-asn1x.h"
35 #include "egg/egg-asn1-defs.h"
36 #include "egg/egg-dn.h"
37 #include "egg/egg-oid.h"
38 #include "egg/egg-hex.h"
43 #include <glib/gi18n-lib.h>
46 * GcrCertificateRenderer:
48 * An implementation of #GcrRenderer which renders certificates.
52 * GcrCertificateRendererClass:
53 * @parent_class: The parent class.
55 * The class for #GcrCertificateRenderer.
65 struct _GcrCertificateRendererPrivate {
66 GcrCertificate *opt_cert;
67 GckAttributes *opt_attrs;
72 static void gcr_renderer_iface_init (GcrRendererIface *iface);
73 static void gcr_renderer_certificate_iface_init (GcrCertificateIface *iface);
75 G_DEFINE_TYPE_WITH_CODE (GcrCertificateRenderer, gcr_certificate_renderer, G_TYPE_OBJECT,
76 G_IMPLEMENT_INTERFACE (GCR_TYPE_RENDERER, gcr_renderer_iface_init);
77 GCR_CERTIFICATE_MIXIN_IMPLEMENT_COMPARABLE ();
78 G_IMPLEMENT_INTERFACE (GCR_TYPE_CERTIFICATE, gcr_renderer_certificate_iface_init);
81 /* -----------------------------------------------------------------------------
86 calculate_label (GcrCertificateRenderer *self)
91 return g_strdup (self->pv->label);
93 if (self->pv->opt_attrs) {
94 if (gck_attributes_find_string (self->pv->opt_attrs, CKA_LABEL, &label))
98 label = gcr_certificate_get_subject_cn (GCR_CERTIFICATE (self));
102 return g_strdup (_("Certificate"));
106 append_extension_basic_constraints (GcrRenderer *renderer,
107 GcrDisplayView *view,
110 gboolean is_ca = FALSE;
114 if (!_gcr_certificate_extension_basic_constraints (data, &is_ca, &path_len))
117 _gcr_display_view_append_heading (view, renderer, _("Basic Constraints"));
119 _gcr_display_view_append_value (view, renderer, _("Certificate Authority"),
120 is_ca ? _("Yes") : _("No"), FALSE);
122 number = g_strdup_printf ("%d", path_len);
123 _gcr_display_view_append_value (view, renderer, _("Max Path Length"),
124 path_len < 0 ? _("Unlimited") : number, FALSE);
131 append_extension_extended_key_usage (GcrRenderer *renderer,
132 GcrDisplayView *view,
139 oids = _gcr_certificate_extension_extended_key_usage (data);
143 _gcr_display_view_append_heading (view, renderer, _("Extended Key Usage"));
145 text = g_string_new ("");
146 for (i = 0; oids[i] != 0; i++) {
148 g_string_append_unichar (text, GCR_DISPLAY_VIEW_LINE_BREAK);
149 g_string_append (text, egg_oid_get_description (oids[i]));
154 _gcr_display_view_append_value (view, renderer, _("Allowed Purposes"),
157 g_string_free (text, TRUE);
163 append_extension_subject_key_identifier (GcrRenderer *renderer,
164 GcrDisplayView *view,
170 keyid = _gcr_certificate_extension_subject_key_identifier (data, &n_keyid);
174 _gcr_display_view_append_heading (view, renderer, _("Subject Key Identifier"));
175 _gcr_display_view_append_hex (view, renderer, _("Key Identifier"), keyid, n_keyid);
182 static const struct {
184 const gchar *description;
185 } usage_descriptions[] = {
186 { GCR_KEY_USAGE_DIGITAL_SIGNATURE, N_("Digital signature") },
187 { GCR_KEY_USAGE_KEY_ENCIPHERMENT, N_("Key encipherment") },
188 { GCR_KEY_USAGE_DATA_ENCIPHERMENT, N_("Data encipherment") },
189 { GCR_KEY_USAGE_KEY_AGREEMENT, N_("Key agreement") },
190 { GCR_KEY_USAGE_KEY_CERT_SIGN, N_("Certificate signature") },
191 { GCR_KEY_USAGE_CRL_SIGN, N_("Revocation list signature") }
195 append_extension_key_usage (GcrRenderer *renderer,
196 GcrDisplayView *view,
203 if (!_gcr_certificate_extension_key_usage (data, &key_usage))
206 text = g_string_new ("");
208 for (i = 0; i < G_N_ELEMENTS (usage_descriptions); i++) {
209 if (key_usage & usage_descriptions[i].usage) {
211 g_string_append_unichar (text, GCR_DISPLAY_VIEW_LINE_BREAK);
212 g_string_append (text, gettext (usage_descriptions[i].description));
216 _gcr_display_view_append_heading (view, renderer, _("Key Usage"));
217 _gcr_display_view_append_value (view, renderer, _("Usages"), text->str, FALSE);
219 g_string_free (text, TRUE);
225 append_extension_subject_alt_name (GcrRenderer *renderer,
226 GcrDisplayView *view,
229 GArray *general_names;
230 GcrGeneralName *general;
233 general_names = _gcr_certificate_extension_subject_alt_name (data);
234 if (general_names == NULL)
237 _gcr_display_view_append_heading (view, renderer, _("Subject Alternative Names"));
239 for (i = 0; i < general_names->len; i++) {
240 general = &g_array_index (general_names, GcrGeneralName, i);
241 if (general->display == NULL)
242 _gcr_display_view_append_hex (view, renderer, general->description,
243 g_bytes_get_data (general->raw, NULL),
244 g_bytes_get_size (general->raw));
246 _gcr_display_view_append_value (view, renderer, general->description,
247 general->display, FALSE);
250 _gcr_general_names_free (general_names);
256 append_extension_hex (GcrRenderer *renderer,
257 GcrDisplayView *view,
264 _gcr_display_view_append_heading (view, renderer, _("Extension"));
267 text = egg_oid_get_description (oid);
268 _gcr_display_view_append_value (view, renderer, _("Identifier"), text, FALSE);
269 _gcr_display_view_append_hex (view, renderer, _("Value"), data, n_data);
275 on_delete_unref_dialog (GtkWidget *widget, GdkEvent *event, gpointer data)
277 g_object_unref (widget);
282 on_export_completed (GObject *source, GAsyncResult *result, gpointer user_data)
284 GtkWindow *parent = GTK_WINDOW (user_data);
285 GcrCertificateExporter *exporter = GCR_CERTIFICATE_EXPORTER (source);
286 GError *error = NULL;
289 if (!_gcr_certificate_exporter_export_finish (exporter, result, &error)) {
290 if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
291 dialog = gtk_message_dialog_new_with_markup (parent,
292 GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR,
293 GTK_BUTTONS_OK, "<big>%s</big>\n\n%s",
294 _("Couldn't export the certificate."),
296 gtk_widget_show (dialog);
297 g_signal_connect (dialog, "delete-event",
298 G_CALLBACK (on_delete_unref_dialog), NULL);
302 /* Matches ref in on_certificate_export */
304 g_object_unref (parent);
308 on_certificate_export (GtkMenuItem *menuitem, gpointer user_data)
310 GcrCertificateRenderer *self = GCR_CERTIFICATE_RENDERER (user_data);
311 GcrCertificateExporter *exporter;
315 label = calculate_label (self);
317 parent = gtk_widget_get_toplevel (GTK_WIDGET (menuitem));
318 if (parent && !GTK_IS_WINDOW (parent))
321 exporter = _gcr_certificate_exporter_new (GCR_CERTIFICATE (self), label,
322 GTK_WINDOW (parent));
326 _gcr_certificate_exporter_export_async (exporter, NULL, on_export_completed,
327 parent ? g_object_ref (parent) : NULL);
330 /* -----------------------------------------------------------------------------
335 gcr_certificate_renderer_init (GcrCertificateRenderer *self)
337 self->pv = (G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_CERTIFICATE_RENDERER, GcrCertificateRendererPrivate));
341 gcr_certificate_renderer_dispose (GObject *obj)
343 GcrCertificateRenderer *self = GCR_CERTIFICATE_RENDERER (obj);
345 if (self->pv->opt_cert)
346 g_object_unref (self->pv->opt_cert);
347 self->pv->opt_cert = NULL;
349 G_OBJECT_CLASS (gcr_certificate_renderer_parent_class)->dispose (obj);
353 gcr_certificate_renderer_finalize (GObject *obj)
355 GcrCertificateRenderer *self = GCR_CERTIFICATE_RENDERER (obj);
357 g_assert (!self->pv->opt_cert);
359 if (self->pv->opt_attrs)
360 gck_attributes_unref (self->pv->opt_attrs);
361 self->pv->opt_attrs = NULL;
363 g_free (self->pv->label);
364 self->pv->label = NULL;
366 G_OBJECT_CLASS (gcr_certificate_renderer_parent_class)->finalize (obj);
370 gcr_certificate_renderer_set_property (GObject *obj, guint prop_id, const GValue *value,
373 GcrCertificateRenderer *self = GCR_CERTIFICATE_RENDERER (obj);
376 case PROP_CERTIFICATE:
377 gcr_certificate_renderer_set_certificate (self, g_value_get_object (value));
380 g_free (self->pv->label);
381 self->pv->label = g_value_dup_string (value);
382 g_object_notify (obj, "label");
383 gcr_renderer_emit_data_changed (GCR_RENDERER (self));
385 case PROP_ATTRIBUTES:
386 gcr_certificate_renderer_set_attributes (self, g_value_get_boxed (value));
389 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
395 gcr_certificate_renderer_get_property (GObject *obj, guint prop_id, GValue *value,
398 GcrCertificateRenderer *self = GCR_CERTIFICATE_RENDERER (obj);
401 case PROP_CERTIFICATE:
402 g_value_set_object (value, self->pv->opt_cert);
405 g_value_take_string (value, calculate_label (self));
407 case PROP_ATTRIBUTES:
408 g_value_set_boxed (value, self->pv->opt_attrs);
411 gcr_certificate_mixin_get_property (obj, prop_id, value, pspec);
417 gcr_certificate_renderer_class_init (GcrCertificateRendererClass *klass)
419 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
420 GckBuilder builder = GCK_BUILDER_INIT;
424 gcr_certificate_renderer_parent_class = g_type_class_peek_parent (klass);
425 g_type_class_add_private (klass, sizeof (GcrCertificateRendererPrivate));
427 gobject_class->dispose = gcr_certificate_renderer_dispose;
428 gobject_class->finalize = gcr_certificate_renderer_finalize;
429 gobject_class->set_property = gcr_certificate_renderer_set_property;
430 gobject_class->get_property = gcr_certificate_renderer_get_property;
433 * GcrCertificateRenderer:certificate:
435 * The certificate to display. May be %NULL.
437 g_object_class_install_property (gobject_class, PROP_CERTIFICATE,
438 g_param_spec_object ("certificate", "Certificate", "Certificate to display.",
439 GCR_TYPE_CERTIFICATE, G_PARAM_READWRITE));
442 * GcrCertificateRenderer:attributes:
444 * The certificate attributes to display. One of the attributes must be
445 * a CKA_VALUE type attribute which contains a DER encoded certificate.
447 g_object_class_install_property (gobject_class, PROP_ATTRIBUTES,
448 g_param_spec_boxed ("attributes", "Attributes", "Certificate pkcs11 attributes",
449 GCK_TYPE_ATTRIBUTES, G_PARAM_READWRITE));
452 * GcrCertificateRenderer:label:
454 * The label to display.
456 g_object_class_install_property (gobject_class, PROP_LABEL,
457 g_param_spec_string ("label", "Label", "Certificate Label",
458 "", G_PARAM_READWRITE));
460 gcr_certificate_mixin_class_init (gobject_class);
462 /* Register this as a renderer which can be loaded */
463 gck_builder_add_ulong (&builder, CKA_CLASS, CKO_CERTIFICATE);
464 gcr_renderer_register (GCR_TYPE_CERTIFICATE_RENDERER, gck_builder_end (&builder));
468 gcr_certificate_renderer_render (GcrRenderer *renderer, GcrViewer *viewer)
470 GcrCertificateRenderer *self;
474 GcrDisplayView *view;
475 GcrCertificate *cert;
485 self = GCR_CERTIFICATE_RENDERER (renderer);
487 if (GCR_IS_DISPLAY_VIEW (viewer)) {
488 view = GCR_DISPLAY_VIEW (viewer);
491 g_warning ("GcrCertificateRenderer only works with internal specific "
492 "GcrViewer returned by gcr_viewer_new().");
496 _gcr_display_view_begin (view, renderer);
497 cert = GCR_CERTIFICATE (self);
499 data = gcr_certificate_get_der_data (cert, &n_data);
501 _gcr_display_view_end (view, renderer);
505 icon = gcr_certificate_get_icon (cert);
506 _gcr_display_view_set_icon (view, GCR_RENDERER (self), icon);
507 g_object_unref (icon);
509 bytes = g_bytes_new_static (data, n_data);
510 asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", bytes);
511 g_return_if_fail (asn != NULL);
512 g_bytes_unref (bytes);
514 display = calculate_label (self);
515 _gcr_display_view_append_title (view, renderer, display);
518 display = egg_dn_read_part (egg_asn1x_node (asn, "tbsCertificate", "subject", "rdnSequence", NULL), "CN");
519 _gcr_display_view_append_content (view, renderer, _("Identity"), display);
522 display = egg_dn_read_part (egg_asn1x_node (asn, "tbsCertificate", "issuer", "rdnSequence", NULL), "CN");
523 _gcr_display_view_append_content (view, renderer, _("Verified by"), display);
526 if (egg_asn1x_get_time_as_date (egg_asn1x_node (asn, "tbsCertificate", "validity", "notAfter", NULL), &date)) {
527 display = g_malloc0 (128);
528 if (!g_date_strftime (display, 128, "%x", &date))
529 g_return_if_reached ();
530 _gcr_display_view_append_content (view, renderer, _("Expires"), display);
534 _gcr_display_view_start_details (view, renderer);
537 _gcr_display_view_append_heading (view, renderer, _("Subject Name"));
538 _gcr_certificate_renderer_append_distinguished_name (renderer, view,
539 egg_asn1x_node (asn, "tbsCertificate", "subject", "rdnSequence", NULL));
542 _gcr_display_view_append_heading (view, renderer, _("Issuer Name"));
543 _gcr_certificate_renderer_append_distinguished_name (renderer, view,
544 egg_asn1x_node (asn, "tbsCertificate", "issuer", "rdnSequence", NULL));
546 /* The Issued Parameters */
547 _gcr_display_view_append_heading (view, renderer, _("Issued Certificate"));
549 if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "tbsCertificate", "version", NULL), &version))
550 g_return_if_reached ();
551 display = g_strdup_printf ("%lu", version + 1);
552 _gcr_display_view_append_value (view, renderer, _("Version"), display, FALSE);
555 number = egg_asn1x_get_integer_as_raw (egg_asn1x_node (asn, "tbsCertificate", "serialNumber", NULL));
556 g_return_if_fail (number != NULL);
557 _gcr_display_view_append_hex (view, renderer, _("Serial Number"),
558 g_bytes_get_data (number, NULL),
559 g_bytes_get_size (number));
560 g_bytes_unref (number);
562 display = g_malloc0 (128);
563 if (egg_asn1x_get_time_as_date (egg_asn1x_node (asn, "tbsCertificate", "validity", "notBefore", NULL), &date)) {
564 if (!g_date_strftime (display, 128, "%Y-%m-%d", &date))
565 g_return_if_reached ();
566 _gcr_display_view_append_value (view, renderer, _("Not Valid Before"), display, FALSE);
568 if (egg_asn1x_get_time_as_date (egg_asn1x_node (asn, "tbsCertificate", "validity", "notAfter", NULL), &date)) {
569 if (!g_date_strftime (display, 128, "%Y-%m-%d", &date))
570 g_return_if_reached ();
571 _gcr_display_view_append_value (view, renderer, _("Not Valid After"), display, FALSE);
576 _gcr_display_view_append_heading (view, renderer, _("Certificate Fingerprints"));
578 _gcr_display_view_append_fingerprint (view, renderer, data, n_data, "SHA1", G_CHECKSUM_SHA1);
579 _gcr_display_view_append_fingerprint (view, renderer, data, n_data, "MD5", G_CHECKSUM_MD5);
581 /* Public Key Info */
582 _gcr_display_view_append_heading (view, renderer, _("Public Key Info"));
583 bits = gcr_certificate_get_key_size (cert);
584 _gcr_certificate_renderer_append_subject_public_key (renderer, view, bits,
585 egg_asn1x_node (asn, "tbsCertificate",
586 "subjectPublicKeyInfo", NULL));
589 for (index = 1; TRUE; ++index) {
590 extension = egg_asn1x_node (asn, "tbsCertificate", "extensions", index, NULL);
591 if (extension == NULL)
593 _gcr_certificate_renderer_append_extension (renderer, view, extension);
597 _gcr_display_view_append_heading (view, renderer, _("Signature"));
598 _gcr_certificate_renderer_append_signature (renderer, view, asn);
600 egg_asn1x_destroy (asn);
601 _gcr_display_view_end (view, renderer);
605 gcr_certificate_renderer_populate_popup (GcrRenderer *self, GcrViewer *viewer,
610 item = gtk_separator_menu_item_new ();
611 gtk_widget_show (item);
612 gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
614 item = gtk_menu_item_new_with_label ("Export Certificate...");
615 gtk_widget_show (item);
616 g_signal_connect_data (item, "activate", G_CALLBACK (on_certificate_export),
617 g_object_ref (self), (GClosureNotify)g_object_unref, 0);
618 gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
622 gcr_renderer_iface_init (GcrRendererIface *iface)
624 iface->populate_popup = gcr_certificate_renderer_populate_popup;
625 iface->render_view = gcr_certificate_renderer_render;
628 static const guchar *
629 gcr_certificate_renderer_get_der_data (GcrCertificate *cert,
632 GcrCertificateRenderer *self = GCR_CERTIFICATE_RENDERER (cert);
633 const GckAttribute *attr;
637 if (self->pv->opt_cert)
638 return gcr_certificate_get_der_data (self->pv->opt_cert, n_data);
640 if (self->pv->opt_attrs) {
641 attr = gck_attributes_find (self->pv->opt_attrs, CKA_VALUE);
642 g_return_val_if_fail (attr, NULL);
643 *n_data = attr->length;
651 gcr_renderer_certificate_iface_init (GcrCertificateIface *iface)
653 iface->get_der_data = gcr_certificate_renderer_get_der_data;
656 /* -----------------------------------------------------------------------------
661 * gcr_certificate_renderer_new:
662 * @certificate: The certificate to display
664 * Create a new certificate renderer to display the certificate.
666 * Returns: (transfer full): a newly allocated #GcrCertificateRenderer, which
667 * should be released with g_object_unref()
669 GcrCertificateRenderer *
670 gcr_certificate_renderer_new (GcrCertificate *certificate)
672 return g_object_new (GCR_TYPE_CERTIFICATE_RENDERER, "certificate", certificate, NULL);
676 * gcr_certificate_renderer_new_for_attributes:
677 * @label: (allow-none): the label to display
678 * @attrs: The attributes to display
680 * Create a new certificate renderer to display the label and attributes. One
681 * of the attributes should be a CKA_VALUE type attribute containing a DER
682 * encoded certificate.
684 * Returns: (transfer full): a newly allocated #GcrCertificateRenderer, which
685 * should be released with g_object_unref()
687 GcrCertificateRenderer *
688 gcr_certificate_renderer_new_for_attributes (const gchar *label, struct _GckAttributes *attrs)
690 return g_object_new (GCR_TYPE_CERTIFICATE_RENDERER, "label", label, "attributes", attrs, NULL);
694 * gcr_certificate_renderer_get_certificate:
695 * @self: The renderer
697 * Get the certificate displayed in the renderer. If no certificate was
698 * explicitly set, then the renderer will return itself since it acts as
699 * a valid certificate.
701 * Returns: (transfer none): The certificate, owned by the renderer.
704 gcr_certificate_renderer_get_certificate (GcrCertificateRenderer *self)
706 g_return_val_if_fail (GCR_IS_CERTIFICATE_RENDERER (self), NULL);
707 if (self->pv->opt_cert)
708 return self->pv->opt_cert;
709 return GCR_CERTIFICATE (self);
713 * gcr_certificate_renderer_set_certificate:
714 * @self: The renderer
715 * @certificate: (allow-none): the certificate to display
717 * Set a certificate to display in the renderer.
720 gcr_certificate_renderer_set_certificate (GcrCertificateRenderer *self, GcrCertificate *certificate)
722 g_return_if_fail (GCR_IS_CERTIFICATE_RENDERER (self));
724 if (self->pv->opt_cert)
725 g_object_unref (self->pv->opt_cert);
726 self->pv->opt_cert = certificate;
727 if (self->pv->opt_cert)
728 g_object_ref (self->pv->opt_cert);
730 if (self->pv->opt_attrs) {
731 gck_attributes_unref (self->pv->opt_attrs);
732 self->pv->opt_attrs = NULL;
735 gcr_renderer_emit_data_changed (GCR_RENDERER (self));
736 g_object_notify (G_OBJECT (self), "certificate");
740 * gcr_certificate_renderer_get_attributes:
741 * @self: The renderer
743 * Get the PKCS\#11 attributes, if any, set for this renderer to display.
745 * Returns: (allow-none) (transfer none): the attributes, owned by the renderer
748 gcr_certificate_renderer_get_attributes (GcrCertificateRenderer *self)
750 g_return_val_if_fail (GCR_IS_CERTIFICATE_RENDERER (self), NULL);
751 return self->pv->opt_attrs;
755 * gcr_certificate_renderer_set_attributes:
756 * @self: The renderer
757 * @attrs: (allow-none): attributes to set
759 * Set the PKCS\#11 attributes for this renderer to display. One of the attributes
760 * should be a CKA_VALUE type attribute containing a DER encoded certificate.
763 gcr_certificate_renderer_set_attributes (GcrCertificateRenderer *self, GckAttributes *attrs)
765 g_return_if_fail (GCR_IS_CERTIFICATE_RENDERER (self));
767 gck_attributes_unref (self->pv->opt_attrs);
768 self->pv->opt_attrs = attrs;
770 if (self->pv->opt_attrs)
771 gck_attributes_ref (self->pv->opt_attrs);
773 if (self->pv->opt_cert) {
774 g_object_unref (self->pv->opt_cert);
775 g_object_notify (G_OBJECT (self), "certificate");
776 self->pv->opt_cert = NULL;
779 gcr_renderer_emit_data_changed (GCR_RENDERER (self));
780 g_object_notify (G_OBJECT (self), "attributes");
785 GcrRenderer *renderer;
786 GcrDisplayView *view;
790 on_parsed_dn_part (guint index,
795 GcrRenderer *renderer = ((AppendDnClosure *)user_data)->renderer;
796 GcrDisplayView *view = ((AppendDnClosure *)user_data)->view;
802 attr = egg_oid_get_name (oid);
803 desc = egg_oid_get_description (oid);
805 /* Combine them into something sane */
807 if (strcmp (attr, desc) == 0)
808 field = g_strdup (attr);
810 field = g_strdup_printf ("%s (%s)", attr, desc);
811 } else if (!attr && !desc) {
812 field = g_strdup ("");
814 field = g_strdup (attr);
816 field = g_strdup (desc);
818 g_assert_not_reached ();
821 display = egg_dn_print_value (oid, value);
823 display = g_strdup ("");
825 _gcr_display_view_append_value (view, renderer, field, display, FALSE);
832 _gcr_certificate_renderer_append_distinguished_name (GcrRenderer *renderer,
833 GcrDisplayView *view,
836 AppendDnClosure closure;
838 g_return_if_fail (GCR_IS_RENDERER (renderer));
839 g_return_if_fail (GCR_IS_DISPLAY_VIEW (view));
840 g_return_if_fail (dn != NULL);
842 closure.renderer = renderer;
844 egg_dn_parse (dn, on_parsed_dn_part, &closure);
848 _gcr_certificate_renderer_append_subject_public_key (GcrRenderer *renderer,
849 GcrDisplayView *view,
851 GNode *subject_public_key)
861 oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (subject_public_key,
862 "algorithm", "algorithm", NULL));
863 text = egg_oid_get_description (oid);
864 _gcr_display_view_append_value (view, renderer, _("Key Algorithm"), text, FALSE);
866 value = egg_asn1x_get_element_raw (egg_asn1x_node (subject_public_key,
867 "algorithm", "parameters", NULL));
869 _gcr_display_view_append_hex (view, renderer, _("Key Parameters"),
870 g_bytes_get_data (value, NULL),
871 g_bytes_get_size (value));
872 g_bytes_unref (value);
876 display = g_strdup_printf ("%u", key_nbits);
877 _gcr_display_view_append_value (view, renderer, _("Key Size"), display, FALSE);
881 value = egg_asn1x_get_element_raw (subject_public_key);
882 raw = gcr_fingerprint_from_subject_public_key_info (g_bytes_get_data (value, NULL),
883 g_bytes_get_size (value),
884 G_CHECKSUM_SHA1, &n_raw);
885 _gcr_display_view_append_hex (view, renderer, _("Key SHA1 Fingerprint"), raw, n_raw);
886 g_bytes_unref (value);
889 value = egg_asn1x_get_bits_as_raw (egg_asn1x_node (subject_public_key, "subjectPublicKey", NULL), &bits);
890 _gcr_display_view_append_hex (view, renderer, _("Public Key"),
891 g_bytes_get_data (value, NULL), bits / 8);
892 g_bytes_unref (value);
896 _gcr_certificate_renderer_append_signature (GcrRenderer *renderer,
897 GcrDisplayView *view,
905 oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "signatureAlgorithm", "algorithm", NULL));
906 text = egg_oid_get_description (oid);
907 _gcr_display_view_append_value (view, renderer, _("Signature Algorithm"), text, FALSE);
909 value = egg_asn1x_get_element_raw (egg_asn1x_node (asn, "signatureAlgorithm", "parameters", NULL));
911 _gcr_display_view_append_hex (view, renderer, _("Signature Parameters"),
912 g_bytes_get_data (value, NULL),
913 g_bytes_get_size (value));
914 g_bytes_unref (value);
917 value = egg_asn1x_get_bits_as_raw (egg_asn1x_node (asn, "signature", NULL), &bits);
918 _gcr_display_view_append_hex (view, renderer, _("Signature"),
919 g_bytes_get_data (value, NULL), bits / 8);
920 g_bytes_unref (value);
924 _gcr_certificate_renderer_append_extension (GcrRenderer *renderer,
925 GcrDisplayView *view,
931 gboolean ret = FALSE;
933 /* Dig out the OID */
934 oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (node, "extnID", NULL));
935 g_return_if_fail (oid);
937 /* Extension value */
938 value = egg_asn1x_get_raw_value (egg_asn1x_node (node, "extnValue", NULL));
940 /* The custom parsers */
941 if (oid == GCR_OID_BASIC_CONSTRAINTS)
942 ret = append_extension_basic_constraints (renderer, view, value);
943 else if (oid == GCR_OID_EXTENDED_KEY_USAGE)
944 ret = append_extension_extended_key_usage (renderer, view, value);
945 else if (oid == GCR_OID_SUBJECT_KEY_IDENTIFIER)
946 ret = append_extension_subject_key_identifier (renderer, view, value);
947 else if (oid == GCR_OID_KEY_USAGE)
948 ret = append_extension_key_usage (renderer, view, value);
949 else if (oid == GCR_OID_SUBJECT_ALT_NAME)
950 ret = append_extension_subject_alt_name (renderer, view, value);
952 /* Otherwise the default raw display */
954 ret = append_extension_hex (renderer, view, oid,
955 g_bytes_get_data (value, NULL),
956 g_bytes_get_size (value));
959 if (ret == TRUE && egg_asn1x_get_boolean (egg_asn1x_node (node, "critical", NULL), &critical)) {
960 _gcr_display_view_append_value (view, renderer, _("Critical"),
961 critical ? _("Yes") : _("No"), FALSE);