evolution-3.6.4/smime/gui/certificate-viewer.c

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>&lt;Not part of certificate&gt;</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 }