No issues found
1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public
4 * License as published by the Free Software Foundation; either
5 * version 2 of the License, or (at your option) version 3.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * Lesser General Public License for more details.
11 *
12 * You should have received a copy of the GNU Lesser General Public
13 * License along with the program; if not, see <http://www.gnu.org/licenses/>
14 *
15 *
16 * Authors:
17 * Chris Toshok <toshok@ximian.com>
18 *
19 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
20 *
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include "certificate-viewer.h"
28
29 #include "e-asn1-object.h"
30
31 #include <glib/gi18n.h>
32
33 #include "e-util/e-util.h"
34 #include "e-util/e-util-private.h"
35
36 typedef struct {
37 GtkBuilder *builder;
38 GtkWidget *dialog;
39 GtkTreeStore *hierarchy_store, *fields_store;
40 GtkWidget *hierarchy_tree, *fields_tree;
41 GtkWidget *field_text;
42 GtkTextTag *text_tag;
43
44 GList *cert_chain;
45 } CertificateViewerData;
46
47 static void
48 free_data (gpointer data,
49 GObject *where_the_object_was)
50 {
51 CertificateViewerData *cvm = data;
52
53 g_list_foreach (cvm->cert_chain, (GFunc) g_object_unref, NULL);
54 g_list_free (cvm->cert_chain);
55
56 g_object_unref (cvm->builder);
57 g_free (cvm);
58 }
59
60 #define NOT_PART_OF_CERT_MARKUP "<i><Not part of certificate></i>"
61
62 static void
63 fill_in_general (CertificateViewerData *cvm_data,
64 ECert *cert)
65 {
66 GtkWidget *label;
67 const gchar *text;
68 gchar *markup;
69
70 /* issued to */
71 label = e_builder_get_widget (cvm_data->builder, "issued-to-cn");
72 if (e_cert_get_cn (cert)) {
73 gtk_label_set_text (GTK_LABEL (label), e_cert_get_cn (cert));
74 }
75 else {
76 gtk_label_set_markup (GTK_LABEL (label), NOT_PART_OF_CERT_MARKUP);
77 }
78
79 label = e_builder_get_widget (cvm_data->builder, "issued-to-o");
80 if (e_cert_get_org (cert)) {
81 gtk_label_set_text (GTK_LABEL (label), e_cert_get_org (cert));
82 }
83 else {
84 gtk_label_set_markup (GTK_LABEL (label), NOT_PART_OF_CERT_MARKUP);
85 }
86
87 label = e_builder_get_widget (cvm_data->builder, "issued-to-ou");
88 if (e_cert_get_org_unit (cert)) {
89 gtk_label_set_text (GTK_LABEL (label), e_cert_get_org_unit (cert));
90 }
91 else {
92 gtk_label_set_markup (GTK_LABEL (label), NOT_PART_OF_CERT_MARKUP);
93 }
94
95 text = e_cert_get_serial_number (cert);
96 label = e_builder_get_widget (cvm_data->builder, "issued-to-serial");
97 gtk_label_set_text (GTK_LABEL (label), text);
98
99 /* issued by */
100 label = e_builder_get_widget (cvm_data->builder, "issued-by-cn");
101 if (e_cert_get_issuer_cn (cert)) {
102 gtk_label_set_text (GTK_LABEL (label), e_cert_get_issuer_cn (cert));
103 }
104 else {
105 gtk_label_set_markup (GTK_LABEL (label), NOT_PART_OF_CERT_MARKUP);
106 }
107
108 label = e_builder_get_widget (cvm_data->builder, "issued-by-o");
109 if (e_cert_get_issuer_org (cert)) {
110 gtk_label_set_text (GTK_LABEL (label), e_cert_get_issuer_org (cert));
111 }
112 else {
113 gtk_label_set_markup (GTK_LABEL (label), NOT_PART_OF_CERT_MARKUP);
114 }
115
116 label = e_builder_get_widget (cvm_data->builder, "issued-by-ou");
117 if (e_cert_get_issuer_org_unit (cert)) {
118 gtk_label_set_text (GTK_LABEL (label), e_cert_get_issuer_org_unit (cert));
119 }
120 else {
121 gtk_label_set_markup (GTK_LABEL (label), NOT_PART_OF_CERT_MARKUP);
122 }
123
124 /* validity */
125 label = e_builder_get_widget (cvm_data->builder, "validity-issued-on");
126 if (e_cert_get_issued_on (cert)) {
127 gtk_label_set_text (GTK_LABEL (label), e_cert_get_issued_on (cert));
128 }
129 else {
130 gtk_label_set_markup (GTK_LABEL (label), NOT_PART_OF_CERT_MARKUP);
131 }
132
133 label = e_builder_get_widget (cvm_data->builder, "validity-expires-on");
134 if (e_cert_get_expires_on (cert)) {
135 gtk_label_set_text (GTK_LABEL (label), e_cert_get_expires_on (cert));
136 }
137 else {
138 gtk_label_set_markup (GTK_LABEL (label), NOT_PART_OF_CERT_MARKUP);
139 }
140
141 /* fingerprints */
142 markup = g_strdup_printf ("<tt>%s</tt>", e_cert_get_sha1_fingerprint (cert));
143 label = e_builder_get_widget (cvm_data->builder, "fingerprints-sha1");
144 gtk_label_set_markup (GTK_LABEL (label), markup);
145 g_free (markup);
146
147 markup = g_strdup_printf ("<tt>%s</tt>", e_cert_get_md5_fingerprint (cert));
148 label = e_builder_get_widget (cvm_data->builder, "fingerprints-md5");
149 gtk_label_set_markup (GTK_LABEL (label), markup);
150 g_free (markup);
151 }
152
153 static void
154 populate_fields_tree (CertificateViewerData *cvm_data,
155 EASN1Object *asn1,
156 GtkTreeIter *root)
157 {
158 GtkTreeIter new_iter;
159
160 /* first insert a node for the current asn1 */
161 gtk_tree_store_insert (cvm_data->fields_store, &new_iter, root, -1);
162 gtk_tree_store_set (
163 cvm_data->fields_store, &new_iter,
164 0, e_asn1_object_get_display_name (asn1),
165 1, asn1,
166 -1);
167
168 if (e_asn1_object_is_valid_container (asn1)) {
169 GList *children = e_asn1_object_get_children (asn1);
170 if (children) {
171 GList *l;
172 for (l = children; l; l = l->next) {
173 EASN1Object *subasn1 = l->data;
174 populate_fields_tree (cvm_data, subasn1, &new_iter);
175 }
176 }
177 g_list_foreach (children, (GFunc) g_object_unref, NULL);
178 g_list_free (children);
179 }
180 }
181
182 static void
183 hierarchy_selection_changed (GtkTreeSelection *selection,
184 CertificateViewerData *cvm_data)
185 {
186 GtkTreeIter iter;
187 GtkTreeModel *model;
188
189 if (gtk_tree_selection_get_selected (selection,
190 &model,
191 &iter)) {
192 EASN1Object *asn1_object;
193 ECert *cert;
194
195 gtk_tree_model_get (
196 model,
197 &iter,
198 1, &cert,
199 -1);
200
201 if (!cert)
202 return;
203
204 /* display the cert's ASN1 structure */
205 asn1_object = e_cert_get_asn1_struct (cert);
206
207 /* wipe out the old model */
208 cvm_data->fields_store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_POINTER);
209 gtk_tree_view_set_model (
210 GTK_TREE_VIEW (cvm_data->fields_tree),
211 GTK_TREE_MODEL (cvm_data->fields_store));
212
213 /* populate the fields from the newly selected cert */
214 populate_fields_tree (cvm_data, asn1_object, NULL);
215 gtk_tree_view_expand_all (GTK_TREE_VIEW (cvm_data->fields_tree));
216 g_object_unref (asn1_object);
217
218 /* and blow away the field value */
219 gtk_text_buffer_set_text (
220 gtk_text_view_get_buffer (GTK_TEXT_VIEW (cvm_data->field_text)),
221 "", 0);
222 }
223 }
224
225 static void
226 fields_selection_changed (GtkTreeSelection *selection,
227 CertificateViewerData *cvm_data)
228 {
229 GtkTreeIter iter;
230 GtkTreeModel *model;
231
232 if (gtk_tree_selection_get_selected (selection,
233 &model,
234 &iter)) {
235 EASN1Object *asn1_object;
236 const gchar *value;
237
238 gtk_tree_model_get (
239 model,
240 &iter,
241 1, &asn1_object,
242 -1);
243
244 value = e_asn1_object_get_display_value (asn1_object);
245
246 gtk_text_buffer_set_text (
247 gtk_text_view_get_buffer (GTK_TEXT_VIEW (cvm_data->field_text)),
248 "", 0);
249
250 if (value) {
251 GtkTextIter text_iter;
252
253 gtk_text_buffer_get_start_iter (
254 gtk_text_view_get_buffer (GTK_TEXT_VIEW (cvm_data->field_text)),
255 &text_iter);
256
257 gtk_text_buffer_insert_with_tags (
258 gtk_text_view_get_buffer (GTK_TEXT_VIEW (cvm_data->field_text)),
259 &text_iter,
260 value, strlen (value),
261 cvm_data->text_tag, NULL);
262 }
263 }
264 }
265
266 static void
267 fill_in_details (CertificateViewerData *cvm_data,
268 ECert *cert)
269 {
270 GList *l;
271 GtkTreeIter *root = NULL;
272 GtkTreeSelection *selection;
273
274 /* hook up all the hierarchy tree foo */
275 cvm_data->hierarchy_store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_OBJECT);
276 cvm_data->hierarchy_tree = e_builder_get_widget (cvm_data->builder, "cert-hierarchy-treeview");
277 gtk_tree_view_set_model (
278 GTK_TREE_VIEW (cvm_data->hierarchy_tree),
279 GTK_TREE_MODEL (cvm_data->hierarchy_store));
280
281 gtk_tree_view_insert_column_with_attributes (
282 GTK_TREE_VIEW (cvm_data->hierarchy_tree),
283 -1, "Cert", gtk_cell_renderer_text_new (),
284 "text", 0, NULL);
285
286 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (cvm_data->hierarchy_tree));
287 g_signal_connect (
288 selection, "changed",
289 G_CALLBACK (hierarchy_selection_changed), cvm_data);
290
291 /* hook up all the fields tree foo */
292 cvm_data->fields_tree = e_builder_get_widget (cvm_data->builder, "cert-fields-treeview");
293
294 gtk_tree_view_insert_column_with_attributes (
295 GTK_TREE_VIEW (cvm_data->fields_tree),
296 -1, "Field", gtk_cell_renderer_text_new (),
297 "text", 0, NULL);
298
299 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (cvm_data->fields_tree));
300 g_signal_connect (
301 selection, "changed",
302 G_CALLBACK (fields_selection_changed), cvm_data);
303
304 /* hook up all the field display foo */
305 cvm_data->field_text = e_builder_get_widget (cvm_data->builder, "cert-field-value-textview");
306
307 /* set the font of the field value viewer to be some fixed
308 * width font to the hex display doesn't look like ass. */
309 cvm_data->text_tag = gtk_text_buffer_create_tag (
310 gtk_text_view_get_buffer (GTK_TEXT_VIEW (cvm_data->field_text)),
311 "mono",
312 "font", "Mono",
313 NULL);
314
315 /* initially populate the hierarchy from the cert's chain */
316 cvm_data->cert_chain = e_cert_get_chain (cert);
317 cvm_data->cert_chain = g_list_reverse (cvm_data->cert_chain);
318 for (l = cvm_data->cert_chain; l; l = l->next) {
319 ECert *c = l->data;
320 const gchar *str;
321 GtkTreeIter new_iter;
322
323 str = e_cert_get_cn (c);
324 if (!str)
325 str = e_cert_get_subject_name (c);
326
327 gtk_tree_store_insert (cvm_data->hierarchy_store, &new_iter, root, -1);
328 gtk_tree_store_set (
329 cvm_data->hierarchy_store, &new_iter,
330 0, str,
331 1, c,
332 -1);
333
334 root = &new_iter;
335 }
336
337 gtk_tree_view_expand_all (GTK_TREE_VIEW (cvm_data->hierarchy_tree));
338 }
339
340 GtkWidget *
341 certificate_viewer_show (ECert *cert)
342 {
343 CertificateViewerData *cvm_data;
344 GtkDialog *dialog;
345 GtkWidget *action_area;
346 gchar *title;
347
348 cvm_data = g_new0 (CertificateViewerData, 1);
349
350 cvm_data->builder = gtk_builder_new ();
351 e_load_ui_builder_definition (cvm_data->builder, "smime-ui.ui");
352
353 cvm_data->dialog = e_builder_get_widget (cvm_data->builder, "certificate-viewer-dialog");
354
355 gtk_widget_realize (cvm_data->dialog);
356
357 dialog = GTK_DIALOG (cvm_data->dialog);
358 action_area = gtk_dialog_get_action_area (dialog);
359 gtk_container_set_border_width (GTK_CONTAINER (action_area), 12);
360
361 title = g_strdup_printf (
362 _("Certificate Viewer: %s"), e_cert_get_window_title (cert));
363 gtk_window_set_title (GTK_WINDOW (cvm_data->dialog), title);
364 g_free (title);
365
366 fill_in_general (cvm_data, cert);
367 fill_in_details (cvm_data, cert);
368
369 g_object_weak_ref (G_OBJECT (cvm_data->dialog), free_data, cvm_data);
370
371 /* gtk_widget_show (cvm_data->dialog);*/
372 return cvm_data->dialog;
373 }