|
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 |
}
|