1 //  gnoMint: a graphical interface for managing a certification authority
2 //  Copyright (C) 2006-2009 David Marín Carreño <davefx@gmail.com>
3 //
4 //  This file is part of gnoMint.
5 //
6 //  gnoMint is free software; you can redistribute it and/or modify
7 //  it under the terms of the GNU General Public License as published by
8 //  the Free Software Foundation; either version 3 of the License, or
9 //  (at your option) any later version.
10 //
11 //  This program is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //  GNU General Public License for more details.
15 //
16 //  You should have received a copy of the GNU General Public License
17 //  along with this program; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 
20 
21 #include <glib-object.h>
22 #include <gtk/gtk.h>
23 #include <libintl.h>
24 #include <stdlib.h>
25 #include <string.h>
26 
27 #include "tls.h"
28 #include "ca_policy.h"
29 #include "certificate_properties.h"
30 
31 #include <glib/gi18n.h>
32 
33 typedef struct
34 {
35 	const gchar *oid;
36 	const gchar *label;
37 } certificate_properties_oid_label_couple_t;
38 
39 enum
40 {
41 	CERTIFICATE_PROPERTIES_COL_NAME = 0,
42 	CERTIFICATE_PROPERTIES_COL_VALUE,
43 	CERTIFICATE_PROPERTIES_N_COLUMNS
44 };
45 
46 typedef void (*certificate_properties_fill_t) (GtkTreeStore *, GtkTreeIter *, gnutls_x509_crt_t *);
47 
48 typedef struct
49 {
50 	const gchar *oid;
51 	certificate_properties_fill_t function;
52 } certificate_properties_oid_function_couple_t;
53 
54 const certificate_properties_oid_label_couple_t certificate_properties_oid_label_table[] = {
55 	{"1.3.6.1.5.5.7.3.1", "TLS WWW Server"},
56 	{"1.3.6.1.5.5.7.3.2", "TLS WWW Client"},
57 	{"1.3.6.1.5.5.7.3.3", "Code signing"},
58 	{"1.3.6.1.5.5.7.3.4", "Email protection"},
59 	{"1.3.6.1.5.5.7.3.8", "Time stamping"},
60 	{"1.3.6.1.5.5.7.3.9", "OCSP signing"},
61 	{"2.5.29.37.0", "Any purpose"},
62 	{"2.5.29.9", "Subject Directory Attributes"},
63 	{"2.5.29.14", "Subject Key Identifier"},
64 	{"2.5.29.15", "Key Usage"},
65 	{"2.5.29.16", "Private Key Usage Period"},
66 	{"2.5.29.17", "Subject Alternative Name"},
67 	{"2.5.29.19", "Basic Constraints"},
68 	{"2.5.29.30", "Name Constraints"},
69 	{"2.5.29.31", "CRL Distribution Points"},
70 	{"2.5.29.32", "Certificate Policies"},
71 	{"2.5.29.33", "Policy Mappings"},
72 	{"2.5.29.35", "Authority Key Identifier"},
73 	{"2.5.29.36", "Policy Constraints"},
74 	{"2.5.29.37", "Extended Key Usage"},
75 	{"2.5.29.46", "Delta CRL Distribution Point"},
76 	{"2.5.29.54", "Inhibit Any-Policy"},
77 	{0, 0},
78 };
79 
80 void __certificate_properties_fill_cert_ext_SubjectKeyIdentifier(GtkTreeStore *, GtkTreeIter *, gnutls_x509_crt_t *);
81 void __certificate_properties_fill_cert_ext_KeyUsage(GtkTreeStore *, GtkTreeIter *, gnutls_x509_crt_t *);
82 void __certificate_properties_fill_cert_ext_SubjectAltName(GtkTreeStore *, GtkTreeIter *, gnutls_x509_crt_t *);
83 void __certificate_properties_fill_cert_ext_BasicConstraints(GtkTreeStore *, GtkTreeIter *, gnutls_x509_crt_t *);
84 void __certificate_properties_fill_cert_ext_CRLDistributionPoints(GtkTreeStore *, GtkTreeIter *, gnutls_x509_crt_t *);
85 void __certificate_properties_fill_cert_ext_AuthorityKeyIdentifier(GtkTreeStore *, GtkTreeIter *, gnutls_x509_crt_t *);
86 void __certificate_properties_fill_cert_ext_ExtKeyUsage(GtkTreeStore *, GtkTreeIter *, gnutls_x509_crt_t *);
87 gchar * __certificate_properties_dump_raw_data(const unsigned char *buffer, size_t buffer_size);
88 const gchar * __certificate_properties_lookup_oid_label(const certificate_properties_oid_label_couple_t *oid_label_table, const gchar *oid);
89 certificate_properties_fill_t __certificate_properties_lookup_oid_function (const certificate_properties_oid_function_couple_t *oid_func_table,
90 									    const gchar *oid);
91 gchar * __certificate_properties_dump_RDNSequence(const gchar *buffer, gsize buffer_size);
92 gchar * __certificate_properties_dump_key_usage(guint key_usage);
93 void __certificate_properties_fill_cert_version(GtkTreeStore *store, GtkTreeIter *parent, gnutls_x509_crt_t *certificate);
94 void __certificate_properties_fill_cert_serialNumber(GtkTreeStore *store, GtkTreeIter *parent, gnutls_x509_crt_t *certificate);
95 void __certificate_properties_fill_cert_signature(GtkTreeStore *store, GtkTreeIter *parent, gnutls_x509_crt_t *certificate);
96 void __certificate_properties_fill_cert_issuer(GtkTreeStore *store, GtkTreeIter *parent, gnutls_x509_crt_t *certificate);
97 void __certificate_properties_fill_cert_validity (GtkTreeStore *store, GtkTreeIter *parent, gnutls_x509_crt_t *certificate);
98 void __certificate_properties_fill_cert_subject (GtkTreeStore *store, GtkTreeIter *parent, gnutls_x509_crt_t *certificate);
99 void __certificate_properties_fill_cert_subjectPublicKeyInfo (GtkTreeStore *store, GtkTreeIter *parent, gnutls_x509_crt_t *certificate);
100 void __certificate_properties_fill_cert_issuerUniqueID (GtkTreeStore *store, GtkTreeIter *parent, gnutls_x509_crt_t *certificate);
101 void __certificate_properties_fill_cert_subjectUniqueID (GtkTreeStore *store, GtkTreeIter *parent, gnutls_x509_crt_t *certificate);
102 void __certificate_properties_fill_cert_ext (GtkTreeStore *store, GtkTreeIter *parent, gnutls_x509_crt_t *certificate);
103 void __certificate_properties_fill_cert (GtkTreeStore *store, GtkTreeIter *parent, gnutls_x509_crt_t *certificate);
104 void __certificate_properties_fill_signatureAlgorithm (GtkTreeStore *store, GtkTreeIter *parent, gnutls_x509_crt_t *certificate);
105 void __certificate_properties_fill_signatureValue (GtkTreeStore *store, GtkTreeIter *parent, gnutls_x509_crt_t *certificate);
106 void __certificate_properties_fill_certificate(GtkTreeStore *store, gnutls_x509_crt_t *certificate);
107 
108 
109 
110 const certificate_properties_oid_function_couple_t certificate_properties_oid_function_table[] = {
111 	{"2.5.29.14", __certificate_properties_fill_cert_ext_SubjectKeyIdentifier},
112 	{"2.5.29.15", __certificate_properties_fill_cert_ext_KeyUsage},
113 	{"2.5.29.17", __certificate_properties_fill_cert_ext_SubjectAltName},
114 	{"2.5.29.19", __certificate_properties_fill_cert_ext_BasicConstraints},
115 	{"2.5.29.31", __certificate_properties_fill_cert_ext_CRLDistributionPoints},
116 	{"2.5.29.35", __certificate_properties_fill_cert_ext_AuthorityKeyIdentifier},
117 	{"2.5.29.37", __certificate_properties_fill_cert_ext_ExtKeyUsage},
118 	{0, 0},
119 };
120 
121 
122 GtkBuilder * certificate_properties_window_gtkb = NULL;
123 
124 void __certificate_properties_populate (const char *certificate_pem);
125 void __certificate_details_populate (const char *certificate_pem);
126 
certificate_properties_display(guint64 cert_id,const char * certificate_pem,gboolean privkey_in_db,gboolean is_ca)127 void certificate_properties_display(guint64 cert_id, const char *certificate_pem, gboolean privkey_in_db,
128 				    gboolean is_ca)
129 {
130 	GObject * widget = NULL;
131 
132 	certificate_properties_window_gtkb = gtk_builder_new();
133 	gtk_builder_add_from_file (certificate_properties_window_gtkb,
134 				   g_build_filename (PACKAGE_DATA_DIR, "gnomint", "certificate_properties_dialog.ui", NULL),
135 				   NULL);
136 	gtk_builder_connect_signals (certificate_properties_window_gtkb, NULL);
137 
138 	__certificate_properties_populate (certificate_pem);
139 	__certificate_details_populate (certificate_pem);
140 
141 	if (! is_ca) {
142 		widget = gtk_builder_get_object (certificate_properties_window_gtkb, "notebook2");
143 		gtk_notebook_remove_page (GTK_NOTEBOOK(widget), 2);
144 	} else {
145 		ca_policy_populate (cert_id);
146 	}
147 
148 	widget = gtk_builder_get_object (certificate_properties_window_gtkb, "certificate_properties_dialog");
149 
150 	g_object_set_data (G_OBJECT(widget), "cert_id", g_strdup_printf("%" G_GUINT64_FORMAT,
151                                                                         cert_id));
152 
153 	gtk_widget_show (GTK_WIDGET(widget));
154 }
155 
156 
__certificate_properties_populate(const char * certificate_pem)157 void __certificate_properties_populate (const char *certificate_pem)
158 {
159 	GObject *widget = NULL;
160 #ifndef WIN32
161 	struct tm tim;
162 #else
163 	struct tm* tim = NULL;
164 #endif
165 	TlsCert * cert = NULL;
166 	gchar model_time_str[100];
167         gchar * aux;
168 	UInt160 * serial_number;
169 
170 	cert = tls_parse_cert_pem (certificate_pem);
171 
172 	serial_number = &cert->serial_number;
173 
174 	widget = gtk_builder_get_object (certificate_properties_window_gtkb, "certActivationDateLabel");
175 #ifndef WIN32
176 	gmtime_r (&cert->activation_time, &tim);
177 	strftime (model_time_str, 100, _("%m/%d/%Y %R GMT"), &tim);
178 #else
179 	tim = gmtime (&cert->activation_time);
180 	strftime (model_time_str, 100, _("%m/%d/%Y %H:%M GMT"), tim);
181 #endif
182 	gtk_label_set_text (GTK_LABEL(widget), model_time_str);
183 
184 	widget = gtk_builder_get_object (certificate_properties_window_gtkb, "certExpirationDateLabel");
185 #ifndef WIN32
186 	gmtime_r (&cert->expiration_time, &tim);
187 	strftime (model_time_str, 100, _("%m/%d/%Y %R GMT"), &tim);
188 #else
189 	tim = gmtime (&cert->expiration_time);
190 	strftime (model_time_str, 100, _("%m/%d/%Y %H:%M GMT"), tim);
191 #endif
192 	gtk_label_set_text (GTK_LABEL(widget), model_time_str);
193 
194 	widget = gtk_builder_get_object (certificate_properties_window_gtkb, "certSNLabel");
195         aux = uint160_strdup_printf (&cert->serial_number);
196 	gtk_label_set_text (GTK_LABEL(widget), aux);
197         g_free (aux);
198 
199 	widget = gtk_builder_get_object (certificate_properties_window_gtkb, "certSubjectCNLabel");
200 	gtk_label_set_text (GTK_LABEL(widget), cert->cn);
201 
202 	widget = gtk_builder_get_object (certificate_properties_window_gtkb, "certSubjectOLabel");
203 	gtk_label_set_text (GTK_LABEL(widget), cert->o);
204 
205 	widget = gtk_builder_get_object (certificate_properties_window_gtkb, "certSubjectOULabel");
206 	gtk_label_set_text (GTK_LABEL(widget), cert->ou);
207 
208 	widget = gtk_builder_get_object (certificate_properties_window_gtkb, "certIssuerCNLabel");
209 	gtk_label_set_text (GTK_LABEL(widget), cert->i_cn);
210 
211 	widget = gtk_builder_get_object (certificate_properties_window_gtkb, "certIssuerOLabel");
212 	gtk_label_set_text (GTK_LABEL(widget), cert->i_o);
213 
214 	widget = gtk_builder_get_object (certificate_properties_window_gtkb, "certIssuerOULabel");
215 	gtk_label_set_text (GTK_LABEL(widget), cert->i_ou);
216 
217 	widget = gtk_builder_get_object (certificate_properties_window_gtkb, "sha1Label");
218 	gtk_label_set_text (GTK_LABEL(widget), cert->sha1);
219 
220 	widget = gtk_builder_get_object (certificate_properties_window_gtkb, "md5Label");
221 	gtk_label_set_text (GTK_LABEL(widget), cert->md5);
222 
223 
224 	if (g_list_length (cert->uses)) {
225 		GValue * valtrue = g_new0 (GValue, 1);
226 		int i;
227 
228 		g_value_init (valtrue, G_TYPE_BOOLEAN);
229 		g_value_set_boolean (valtrue, TRUE);
230 
231 		widget = gtk_builder_get_object (certificate_properties_window_gtkb, "certPropSeparator");
232 		gtk_widget_show (GTK_WIDGET(widget));
233 
234 		widget = gtk_builder_get_object (certificate_properties_window_gtkb, "vboxCertCapabilities");
235 
236 		for (i = g_list_length(cert->uses) - 1; i >= 0; i--) {
237 			GtkLabel *label = NULL;
238 			label = GTK_LABEL(gtk_label_new ((gchar *) g_list_nth_data (cert->uses, i)));
239 			gtk_misc_set_alignment (GTK_MISC(label), 0.0, 0.5);
240 			gtk_box_pack_end (GTK_BOX(widget), GTK_WIDGET(label), 0, 0, 0);
241 		}
242 		gtk_widget_show_all (GTK_WIDGET(widget));
243 
244 		g_free (valtrue);
245 	}
246 
247 
248 
249 	tls_cert_free (cert);
250 
251 	return;
252 }
253 
certificate_properties_close_clicked(const char * certificate_pem)254 G_MODULE_EXPORT void certificate_properties_close_clicked (const char *certificate_pem)
255 {
256 	GObject *widget = gtk_builder_get_object (certificate_properties_window_gtkb, "certificate_properties_dialog");
257 	gtk_widget_destroy (GTK_WIDGET(widget));
258 }
259 
260 
__certificate_properties_dump_raw_data(const unsigned char * buffer,size_t buffer_size)261 gchar * __certificate_properties_dump_raw_data(const unsigned char *buffer, size_t buffer_size)
262 {
263 	const gint BYTES_PER_LINE = 16;
264 	gchar *result = g_new0 (gchar, 4 * buffer_size);
265 	size_t i;
266 	gchar *result_iterator = result;
267 	if (!result)
268 	{
269 		fprintf(stderr, "Error: (%s,%d): %s\n", __FILE__, __LINE__, "Not enough memory\n");
270 		return result;
271 	}
272 	for (i = 0; i < buffer_size; i++)
273 	{
274 		result_iterator += sprintf(result_iterator, "%02x:", buffer[i]);
275 		if ((i % BYTES_PER_LINE) == BYTES_PER_LINE - 1)
276 			*result_iterator++ = '\n';
277 	}
278 	if ((i % BYTES_PER_LINE) == 0)
279 		*(result_iterator - 1) = 0;
280 	return result;
281 }
282 
283 
__certificate_properties_lookup_oid_label(const certificate_properties_oid_label_couple_t * oid_label_table,const gchar * oid)284 const gchar * __certificate_properties_lookup_oid_label(const certificate_properties_oid_label_couple_t *oid_label_table, const gchar *oid)
285 {
286 	const certificate_properties_oid_label_couple_t *i;
287 
288 	if (!oid)
289 		return 0;
290 
291 	for (i = certificate_properties_oid_label_table; i->oid; i++)
292 		if (strcmp(i->oid, oid) == 0)
293 			break;
294 	return _(i->label);
295 }
296 
297 
__certificate_properties_lookup_oid_function(const certificate_properties_oid_function_couple_t * oid_func_table,const gchar * oid)298 certificate_properties_fill_t __certificate_properties_lookup_oid_function (const certificate_properties_oid_function_couple_t *oid_func_table,
299 									    const gchar *oid)
300 {
301 	const certificate_properties_oid_function_couple_t *i;
302 	if (!oid)
303 		return 0;
304 	for (i = oid_func_table; i->oid; i++)
305 		if (strcmp(i->oid, oid) == 0)
306 			break;
307 	return i->function;
308 }
309 
310 
__certificate_properties_dump_RDNSequence(const gchar * buffer,gsize buffer_size)311 gchar * __certificate_properties_dump_RDNSequence(const gchar *buffer, gsize buffer_size)
312 {
313 	const char ESCAPE = '\\';
314 	const char SEPARATOR = ',';
315 	gchar *result = g_new0 (gchar, buffer_size + 1);
316 	gsize i;
317 	gchar *result_iterator = result;
318 	gint previous_was_escape = 0;
319 	if (! result) {
320 		fprintf(stderr, "Error: (%s,%d): %s\n", __FILE__, __LINE__, "Not enough memory\n");
321 		return result;
322 	}
323 
324 	for (i = 0; i < buffer_size; i++)
325 	{
326 		if (previous_was_escape)
327 		{
328 			*result_iterator++ = *buffer++;
329 			previous_was_escape = 0;
330 		}
331 		else if (*buffer == ESCAPE)
332 		{
333 			buffer++;
334 			previous_was_escape = 1;
335 		}
336 		else if (*buffer == SEPARATOR)
337 		{
338 			*result_iterator++ = '\n';
339 			buffer++;
340 		}
341 		else
342 			*result_iterator++ = *buffer++;
343 	}
344 	*result_iterator++ = 0;
345 	return result;
346 }
347 
__certificate_properties_dump_key_usage(guint key_usage)348 gchar * __certificate_properties_dump_key_usage(guint key_usage)
349 {
350 	const gint BUFFER_SIZE_MAX = 1024;
351 	gchar *result = g_new0 (gchar, BUFFER_SIZE_MAX + 1);
352 	gchar *buffer_iterator = result;
353 	if (key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE)
354 		buffer_iterator += sprintf(buffer_iterator, "%s\n", _("Digital signature"));
355 	if (key_usage & GNUTLS_KEY_NON_REPUDIATION)
356 		buffer_iterator += sprintf(buffer_iterator, "%s\n", _("Non repudiation"));
357 	if (key_usage & GNUTLS_KEY_KEY_ENCIPHERMENT)
358 		buffer_iterator += sprintf(buffer_iterator, "%s\n", _("Key encipherment"));
359 	if (key_usage & GNUTLS_KEY_DATA_ENCIPHERMENT)
360 		buffer_iterator += sprintf(buffer_iterator, "%s\n", _("Data encipherment"));
361 	if (key_usage & GNUTLS_KEY_KEY_AGREEMENT)
362 		buffer_iterator += sprintf(buffer_iterator, "%s\n", _("Key agreement"));
363 	if (key_usage & GNUTLS_KEY_KEY_CERT_SIGN)
364 		buffer_iterator += sprintf(buffer_iterator, "%s\n", _("Certificate signing"));
365 	if (key_usage & GNUTLS_KEY_CRL_SIGN)
366 		buffer_iterator += sprintf(buffer_iterator, "%s\n", _("CRL signing"));
367 	if (key_usage & GNUTLS_KEY_ENCIPHER_ONLY)
368 		buffer_iterator += sprintf(buffer_iterator, "%s\n", _("Key encipherment only"));
369 	if (key_usage & GNUTLS_KEY_DECIPHER_ONLY)
370 		buffer_iterator += sprintf(buffer_iterator, "%s\n", _("Key decipherment only"));
371 	*(buffer_iterator - 1) = 0;
372 	return result;
373 }
374 
__certificate_properties_fill_cert_version(GtkTreeStore * store,GtkTreeIter * parent,gnutls_x509_crt_t * certificate)375 void __certificate_properties_fill_cert_version(GtkTreeStore *store, GtkTreeIter *parent, gnutls_x509_crt_t *certificate)
376 {
377 	gint result;
378 	gchar value[4];
379 	GtkTreeIter j;
380 
381 	result = gnutls_x509_crt_get_version(*certificate);
382 	sprintf(value, "v%d", result);
383 	gtk_tree_store_append(store, &j, parent);
384 	gtk_tree_store_set(store, &j, CERTIFICATE_PROPERTIES_COL_NAME, _("Version"), CERTIFICATE_PROPERTIES_COL_VALUE, value, -1);
385 }
386 
__certificate_properties_fill_cert_serialNumber(GtkTreeStore * store,GtkTreeIter * parent,gnutls_x509_crt_t * certificate)387 void __certificate_properties_fill_cert_serialNumber(GtkTreeStore *store, GtkTreeIter *parent, gnutls_x509_crt_t *certificate)
388 {
389 	gint result;
390 	gsize buffer_size = 0;
391 	GtkTreeIter j;
392 	gchar *buffer = NULL;
393 	gchar *value = NULL;
394 
395 	result = gnutls_x509_crt_get_serial(*certificate, 0, &buffer_size);
396 	if (result != GNUTLS_E_SHORT_MEMORY_BUFFER) {
397 		fprintf(stderr, "Error: (%s,%d): %s\n", __FILE__, __LINE__, gnutls_strerror(result));
398 		return;
399 	}
400 	buffer = g_new0(gchar, buffer_size);
401 
402 	if (!buffer) {
403 		fprintf(stderr, "Error: (%s,%d): %s\n", __FILE__, __LINE__, "Not enough memory!");
404 		return;
405 	}
406 
407 	result = gnutls_x509_crt_get_serial(*certificate, buffer, &buffer_size);
408 
409 	if (result < 0) {
410 		fprintf(stderr, "Error: (%s,%d): %s\n", __FILE__, __LINE__, gnutls_strerror(result));
411 		return;
412 	}
413 
414 	value = __certificate_properties_dump_raw_data((unsigned char *) buffer, buffer_size);
415 
416 	g_free(buffer);
417 
418 	gtk_tree_store_append(store, &j, parent);
419 	gtk_tree_store_set(store, &j, CERTIFICATE_PROPERTIES_COL_NAME, _("Serial Number"), CERTIFICATE_PROPERTIES_COL_VALUE, value, -1);
420 
421 	g_free(value);
422 }
423 
__certificate_properties_fill_cert_signature(GtkTreeStore * store,GtkTreeIter * parent,gnutls_x509_crt_t * certificate)424 void __certificate_properties_fill_cert_signature(GtkTreeStore *store, GtkTreeIter *parent, gnutls_x509_crt_t *certificate)
425 {
426 	int result;
427 	GtkTreeIter j;
428 	GtkTreeIter k;
429         const gchar *name = NULL;
430 
431 	result = gnutls_x509_crt_get_signature_algorithm(*certificate);
432 	name = gnutls_sign_algorithm_get_name(result);
433 
434 	gtk_tree_store_append(store, &j, parent);
435 	gtk_tree_store_set(store, &j, CERTIFICATE_PROPERTIES_COL_NAME, _("Signature"), -1);
436 
437 	gtk_tree_store_append(store, &k, &j);
438 	gtk_tree_store_set(store, &k, CERTIFICATE_PROPERTIES_COL_NAME, _("Algorithm"), CERTIFICATE_PROPERTIES_COL_VALUE, name, -1);
439 
440 	gtk_tree_store_append(store, &k, &j);
441 	gtk_tree_store_set(store, &k, CERTIFICATE_PROPERTIES_COL_NAME, _("Parameters"), CERTIFICATE_PROPERTIES_COL_VALUE, _("(unknown)"), -1);
442 }
443 
__certificate_properties_fill_cert_issuer(GtkTreeStore * store,GtkTreeIter * parent,gnutls_x509_crt_t * certificate)444 void __certificate_properties_fill_cert_issuer(GtkTreeStore *store, GtkTreeIter *parent, gnutls_x509_crt_t *certificate)
445 {
446 	int result;
447 	size_t buffer_size = 0;
448 	gchar * buffer = NULL;
449 	gchar * value = NULL;
450 	GtkTreeIter j;
451 
452 	result = gnutls_x509_crt_get_issuer_dn(*certificate, 0, &buffer_size);
453 	if (result != GNUTLS_E_SHORT_MEMORY_BUFFER) {
454 		fprintf(stderr, "Error: (%s,%d): %s\n", __FILE__, __LINE__, gnutls_strerror(result));
455 		return;
456 	}
457 	buffer = g_new (gchar, buffer_size);
458 	if (!buffer) {
459 		fprintf(stderr, "Error: (%s,%d): %s\n", __FILE__, __LINE__, "Not enough memory!");
460 		return;
461 	}
462 	result = gnutls_x509_crt_get_issuer_dn(*certificate, buffer, &buffer_size);
463 	if (result < 0) {
464 		fprintf(stderr, "Error: (%s,%d): %s\n", __FILE__, __LINE__, gnutls_strerror(result));
465 		return;
466 	}
467 
468 	value = __certificate_properties_dump_RDNSequence(buffer, buffer_size);
469 
470 	g_free(buffer);
471 
472 	gtk_tree_store_append(store, &j, parent);
473 	gtk_tree_store_set(store, &j, CERTIFICATE_PROPERTIES_COL_NAME, _("Issuer"), CERTIFICATE_PROPERTIES_COL_VALUE, value, -1);
474 
475 	g_free(value);
476 }
477 
__certificate_properties_fill_cert_validity(GtkTreeStore * store,GtkTreeIter * parent,gnutls_x509_crt_t * certificate)478 void __certificate_properties_fill_cert_validity (GtkTreeStore *store, GtkTreeIter *parent, gnutls_x509_crt_t *certificate)
479 {
480 	time_t not_before;
481 #ifndef WIN32
482 	struct tm not_before_broken_down_time;
483 #else
484 	struct tm *not_before_broken_down_time = NULL;
485 #endif
486 	gchar not_before_asctime[32];
487 	time_t not_after;
488 #ifndef WIN32
489 	struct tm not_after_broken_down_time;
490 #else
491 	struct tm *not_after_broken_down_time = NULL;
492 #endif
493 	gchar not_after_asctime[32];
494 	GtkTreeIter j;
495 	GtkTreeIter k;
496 
497 #ifndef WIN32
498 	not_before = gnutls_x509_crt_get_activation_time(*certificate);
499 	gmtime_r (&not_before, &not_before_broken_down_time);
500 	asctime_r(&not_before_broken_down_time, not_before_asctime);
501 	not_before_asctime[strlen(not_before_asctime) - 1] = 0;
502 #else
503 	not_before = gnutls_x509_crt_get_activation_time(*certificate);
504 	not_before_broken_down_time = gmtime(&not_before);
505 	snprintf(not_before_asctime, sizeof(not_before_asctime), "%s", asctime(not_before_broken_down_time));
506 	// not_before_asctime[strlen(not_before_asctime) - 1] = 0; // ???
507 #endif
508 
509 #ifndef WIN32
510 	not_after = gnutls_x509_crt_get_expiration_time(*certificate);
511 	gmtime_r(&not_after, &not_after_broken_down_time);
512 	asctime_r(&not_after_broken_down_time, not_after_asctime);
513 	not_after_asctime[strlen(not_after_asctime) - 1] = 0;
514 #else
515 	not_after = gnutls_x509_crt_get_expiration_time(*certificate);
516 	not_after_broken_down_time = gmtime(&not_after);
517 	snprintf(not_after_asctime, sizeof(not_after_asctime), "%s", asctime(not_after_broken_down_time));
518 	// not_after_asctime[strlen(not_after_asctime) - 1] = 0; // ???
519 #endif
520 
521 	gtk_tree_store_append(store, &j, parent);
522 	gtk_tree_store_set(store, &j, CERTIFICATE_PROPERTIES_COL_NAME, _("Validity"), -1);
523 
524 	gtk_tree_store_append(store, &k, &j);
525 	gtk_tree_store_set(store, &k, CERTIFICATE_PROPERTIES_COL_NAME, _("Not Before"), CERTIFICATE_PROPERTIES_COL_VALUE, not_before_asctime, -1);
526 
527 	gtk_tree_store_append(store, &k, &j);
528 	gtk_tree_store_set(store, &k, CERTIFICATE_PROPERTIES_COL_NAME, _("Not After"), CERTIFICATE_PROPERTIES_COL_VALUE, not_after_asctime, -1);
529 }
530 
__certificate_properties_fill_cert_subject(GtkTreeStore * store,GtkTreeIter * parent,gnutls_x509_crt_t * certificate)531 void __certificate_properties_fill_cert_subject (GtkTreeStore *store, GtkTreeIter *parent, gnutls_x509_crt_t *certificate)
532 {
533 	int result;
534 	size_t buffer_size = 0;
535 	gchar *buffer = NULL;
536 	gchar *value = NULL;
537 	GtkTreeIter j;
538 
539 	result = gnutls_x509_crt_get_dn(*certificate, 0, &buffer_size);
540 	if (result != GNUTLS_E_SHORT_MEMORY_BUFFER) {
541 		fprintf(stderr, "Error: (%s,%d): %s\n", __FILE__, __LINE__, gnutls_strerror(result));
542 		return;
543 	}
544 	buffer = g_new0 (gchar, buffer_size);
545 	if (!buffer) {
546 		fprintf(stderr, "Error: (%s,%d): %s\n", __FILE__, __LINE__, "Not enough memory!");
547 		return;
548 	}
549 
550 	result = gnutls_x509_crt_get_dn(*certificate, buffer, &buffer_size);
551 	if (result < 0) {
552 		fprintf(stderr, "Error: (%s,%d): %s\n", __FILE__, __LINE__, gnutls_strerror(result));
553 		return;
554 	}
555 	value = __certificate_properties_dump_RDNSequence(buffer, buffer_size);
556 
557 	g_free(buffer);
558 
559 	gtk_tree_store_append(store, &j, parent);
560 	gtk_tree_store_set(store, &j, CERTIFICATE_PROPERTIES_COL_NAME, _("Subject"), CERTIFICATE_PROPERTIES_COL_VALUE, value, -1);
561 
562 	g_free(value);
563 }
564 
__certificate_properties_fill_cert_subjectPublicKeyInfo(GtkTreeStore * store,GtkTreeIter * parent,gnutls_x509_crt_t * certificate)565 void __certificate_properties_fill_cert_subjectPublicKeyInfo (GtkTreeStore *store,
566                                                               GtkTreeIter *parent,
567                                                               gnutls_x509_crt_t *certificate)
568 {
569 	int result;
570 	unsigned int bits = 0;
571 	const gchar * name = NULL;
572 	GtkTreeIter j;
573 	GtkTreeIter k;
574 	GtkTreeIter l;
575 	gchar *value;
576 	GtkTreeIter m;
577 	gnutls_datum_t modulus, publicExponent;
578 	gnutls_datum_t p, q, g, y;
579 
580 	result = gnutls_x509_crt_get_pk_algorithm(*certificate, &bits);
581 	name = gnutls_pk_algorithm_get_name(result);
582 
583 	gtk_tree_store_append(store, &j, parent);
584 	gtk_tree_store_set(store, &j, CERTIFICATE_PROPERTIES_COL_NAME, _("Subject Public Key Info"), -1);
585 
586 	gtk_tree_store_append(store, &k, &j);
587 	gtk_tree_store_set(store, &k, CERTIFICATE_PROPERTIES_COL_NAME, _("Algorithm"), -1);
588 
589 	gtk_tree_store_append(store, &l, &k);
590 	gtk_tree_store_set(store, &l, CERTIFICATE_PROPERTIES_COL_NAME, _("Algorithm"), CERTIFICATE_PROPERTIES_COL_VALUE, name, -1);
591 
592 	switch (result) {
593 	case GNUTLS_PK_RSA:
594 		gtk_tree_store_append(store, &l, &k);
595 		gtk_tree_store_set(store, &l, CERTIFICATE_PROPERTIES_COL_NAME, _("Parameters"), CERTIFICATE_PROPERTIES_COL_VALUE, _("(unknown)"), -1);
596 		gtk_tree_store_append(store, &k, &j);
597 		gtk_tree_store_set(store, &k, CERTIFICATE_PROPERTIES_COL_NAME, _("RSA PublicKey"), -1);
598 		result = gnutls_x509_crt_get_pk_rsa_raw(*certificate, &modulus, &publicExponent);
599 		if (result < 0) {
600 			fprintf(stderr, "Error: (%s,%d): %s\n", __FILE__, __LINE__, gnutls_strerror(result));
601 			break;
602 		}
603 		value = __certificate_properties_dump_raw_data(modulus.data, modulus.size);
604 		gnutls_free(modulus.data);
605 
606 		gtk_tree_store_append(store, &l, &k);
607 		gtk_tree_store_set(store, &l, CERTIFICATE_PROPERTIES_COL_NAME, _("Modulus"), CERTIFICATE_PROPERTIES_COL_VALUE, value, -1);
608 		g_free(value);
609 
610 		value = __certificate_properties_dump_raw_data(publicExponent.data, publicExponent.size);
611 		gnutls_free(publicExponent.data);
612 		gtk_tree_store_append(store, &l, &k);
613 		gtk_tree_store_set(store, &l, CERTIFICATE_PROPERTIES_COL_NAME, _("Public Exponent"), CERTIFICATE_PROPERTIES_COL_VALUE, value, -1);
614 		g_free(value);
615 		break;
616 	case GNUTLS_PK_DSA:
617 		result = gnutls_x509_crt_get_pk_dsa_raw(*certificate, &p, &q, &g, &y);
618 		if (result < 0) {
619 			fprintf(stderr, "Error: (%s,%d): %s\n", __FILE__, __LINE__, gnutls_strerror(result));
620 			break;
621 		}
622 		gtk_tree_store_append(store, &l, &k);
623 		gtk_tree_store_set(store, &l, CERTIFICATE_PROPERTIES_COL_NAME, _("Parameters"), -1);
624 
625 		value = __certificate_properties_dump_raw_data(p.data, p.size);
626 		gnutls_free(p.data);
627 		gtk_tree_store_append(store, &m, &l);
628 		gtk_tree_store_set(store, &m, CERTIFICATE_PROPERTIES_COL_NAME, "p", CERTIFICATE_PROPERTIES_COL_VALUE, value, -1);
629 		g_free(value);
630 
631 		value = __certificate_properties_dump_raw_data(q.data, q.size);
632 		gnutls_free(q.data);
633 		gtk_tree_store_append(store, &m, &l);
634 		gtk_tree_store_set(store, &m, CERTIFICATE_PROPERTIES_COL_NAME, "p", CERTIFICATE_PROPERTIES_COL_VALUE, value, -1);
635 		g_free(value);
636 
637 		value = __certificate_properties_dump_raw_data(g.data, g.size);
638 		gnutls_free(g.data);
639 		gtk_tree_store_append(store, &m, &l);
640 		gtk_tree_store_set(store, &m, CERTIFICATE_PROPERTIES_COL_NAME, "g", CERTIFICATE_PROPERTIES_COL_VALUE, value, -1);
641 		g_free(value);
642 
643 		value = __certificate_properties_dump_raw_data(y.data, y.size);
644 		gnutls_free(y.data);
645 		gtk_tree_store_append(store, &k, &j);
646 		gtk_tree_store_set(store, &k, CERTIFICATE_PROPERTIES_COL_NAME, _("DSA PublicKey"), CERTIFICATE_PROPERTIES_COL_VALUE, value, -1);
647 		g_free(value);
648 		break;
649 	default:
650 		gtk_tree_store_append(store, &l, &k);
651 		gtk_tree_store_set(store, &l, CERTIFICATE_PROPERTIES_COL_NAME, _("Parameters"), CERTIFICATE_PROPERTIES_COL_VALUE, _("(unknown)"), -1);
652 		gtk_tree_store_append(store, &k, &j);
653 		gtk_tree_store_set(store, &k, CERTIFICATE_PROPERTIES_COL_NAME, _("Subject Public Key"), CERTIFICATE_PROPERTIES_COL_VALUE, _("(unknown)"), -1);
654 		break;
655 	}
656 }
657 
__certificate_properties_fill_cert_issuerUniqueID(GtkTreeStore * store,GtkTreeIter * parent,gnutls_x509_crt_t * certificate)658 void __certificate_properties_fill_cert_issuerUniqueID (GtkTreeStore *store,
659 								  GtkTreeIter *parent,
660 								  gnutls_x509_crt_t *certificate)
661 {
662 	GtkTreeIter j;
663 	gtk_tree_store_append(store, &j, parent);
664 	gtk_tree_store_set(store, &j, CERTIFICATE_PROPERTIES_COL_NAME, _("Issuer Unique ID"), CERTIFICATE_PROPERTIES_COL_VALUE, _("(unknown)"), -1);
665 }
666 
__certificate_properties_fill_cert_subjectUniqueID(GtkTreeStore * store,GtkTreeIter * parent,gnutls_x509_crt_t * certificate)667 void __certificate_properties_fill_cert_subjectUniqueID (GtkTreeStore *store,
668 								   GtkTreeIter *parent,
669 								   gnutls_x509_crt_t *certificate)
670 {
671 	GtkTreeIter j;
672 	gtk_tree_store_append(store, &j, parent);
673 	gtk_tree_store_set(store, &j, CERTIFICATE_PROPERTIES_COL_NAME, _("Subject Unique ID"), CERTIFICATE_PROPERTIES_COL_VALUE, _("(unknown)"), -1);
674 }
675 
__certificate_properties_fill_cert_ext_SubjectKeyIdentifier(GtkTreeStore * store,GtkTreeIter * parent,gnutls_x509_crt_t * certificate)676 void __certificate_properties_fill_cert_ext_SubjectKeyIdentifier (GtkTreeStore *store,
677 										   GtkTreeIter *parent,
678 										   gnutls_x509_crt_t *certificate)
679 {
680 	guint critical;
681 	gint result;
682 	const gint BUFFER_SIZE_MAX = 256;
683 	gchar buffer[BUFFER_SIZE_MAX];
684 	gsize buffer_size = BUFFER_SIZE_MAX;
685 	gchar *hex_buffer;
686 	GtkTreeIter l;
687 
688 	result = gnutls_x509_crt_get_subject_key_id(*certificate, buffer, &buffer_size, &critical);
689 	if (result < 0) {
690 		fprintf(stderr, "Error: %s\n", gnutls_strerror(result));
691 		return;
692 	}
693 	hex_buffer = __certificate_properties_dump_raw_data((guchar *) buffer, buffer_size);
694 	gtk_tree_store_append(store, &l, parent);
695 	gtk_tree_store_set(store, &l, CERTIFICATE_PROPERTIES_COL_NAME, _("Value"), CERTIFICATE_PROPERTIES_COL_VALUE, hex_buffer, -1);
696 	g_free(hex_buffer);
697 }
698 
__certificate_properties_fill_cert_ext_KeyUsage(GtkTreeStore * store,GtkTreeIter * parent,gnutls_x509_crt_t * certificate)699 void __certificate_properties_fill_cert_ext_KeyUsage (GtkTreeStore *store,
700 								       GtkTreeIter *parent,
701 								       gnutls_x509_crt_t *certificate)
702 {
703 	guint critical;
704 	guint key_usage;
705 	gint result;
706         gchar * buffer = NULL;
707         GtkTreeIter l;
708 
709 	result = gnutls_x509_crt_get_key_usage(*certificate, &key_usage, &critical);
710 
711 	if (result < 0) {
712 		fprintf(stderr, "Error: %s\n", gnutls_strerror(result));
713 		return;
714 	}
715 	buffer = __certificate_properties_dump_key_usage(key_usage);
716 
717 	gtk_tree_store_append(store, &l, parent);
718 	gtk_tree_store_set(store, &l, CERTIFICATE_PROPERTIES_COL_NAME, _("Value"), CERTIFICATE_PROPERTIES_COL_VALUE, buffer, -1);
719 	g_free(buffer);
720 }
721 
__certificate_properties_fill_cert_ext_SubjectAltName(GtkTreeStore * store,GtkTreeIter * parent,gnutls_x509_crt_t * certificate)722 void __certificate_properties_fill_cert_ext_SubjectAltName (GtkTreeStore *store,
723 									     GtkTreeIter *parent,
724 									     gnutls_x509_crt_t *certificate)
725 {
726 	gint i;
727 	for (i = 0; i < 1; i++)
728 	{
729 		gint result;
730 		guint critical;
731 		const gint BUFFER_SIZE_MAX = 1024;
732 		gchar buffer[BUFFER_SIZE_MAX];
733 		gsize buffer_size = BUFFER_SIZE_MAX;
734 		gchar *hex_buffer;
735 		GtkTreeIter l;
736 
737 		result = gnutls_x509_crt_get_subject_alt_name(*certificate, i, buffer, &buffer_size, &critical);
738 
739 		if (result == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
740 			fprintf(stderr, "Error: (%s,%d): %s\n", __FILE__, __LINE__, gnutls_strerror(result));
741 			break;
742 		}
743 
744 		if (result == GNUTLS_E_SHORT_MEMORY_BUFFER) {
745 			fprintf(stderr, "Error: (%s,%d): %s\n", __FILE__, __LINE__, gnutls_strerror(result));
746 			break;
747 		}
748 
749 		if (result < 0) {
750 			fprintf(stderr, "Error: (%s,%d): %s\n", __FILE__, __LINE__, gnutls_strerror(result));
751 			break;
752 		}
753 
754 		switch (result) {
755 		case GNUTLS_SAN_DNSNAME:
756 			gtk_tree_store_append(store, &l, parent);
757 			gtk_tree_store_set(store, &l, CERTIFICATE_PROPERTIES_COL_NAME, _("DNS Name"),
758 					   CERTIFICATE_PROPERTIES_COL_VALUE, buffer, -1);
759 			break;
760 		case GNUTLS_SAN_RFC822NAME:
761 			gtk_tree_store_append(store, &l, parent);
762 			gtk_tree_store_set(store, &l, CERTIFICATE_PROPERTIES_COL_NAME, _("RFC822 Name"),
763 					   CERTIFICATE_PROPERTIES_COL_VALUE, buffer, -1);
764 			break;
765 		case GNUTLS_SAN_URI:
766 			gtk_tree_store_append(store, &l, parent);
767 			gtk_tree_store_set(store, &l, CERTIFICATE_PROPERTIES_COL_NAME, _("URI"),
768 					   CERTIFICATE_PROPERTIES_COL_VALUE, buffer, -1);
769 			break;
770 		case GNUTLS_SAN_IPADDRESS:
771 			hex_buffer = __certificate_properties_dump_raw_data ((guchar *) buffer, buffer_size);
772 			gtk_tree_store_append(store, &l, parent);
773 			gtk_tree_store_set(store, &l, CERTIFICATE_PROPERTIES_COL_NAME, _("IP"),
774 					   CERTIFICATE_PROPERTIES_COL_VALUE, hex_buffer, -1);
775 			g_free(hex_buffer);
776 			break;
777 		case GNUTLS_SAN_DN:
778 			hex_buffer = __certificate_properties_dump_RDNSequence (buffer, buffer_size);
779 			gtk_tree_store_append(store, &l, parent);
780 			gtk_tree_store_set(store, &l, CERTIFICATE_PROPERTIES_COL_NAME, _("Directory Name"),
781 					   CERTIFICATE_PROPERTIES_COL_VALUE, hex_buffer, -1);
782 			g_free(hex_buffer);
783 			break;
784 		default:
785 			hex_buffer = __certificate_properties_dump_raw_data((guchar *) buffer, buffer_size);
786 			gtk_tree_store_append (store, &l, parent);
787 			gtk_tree_store_set (store, &l, CERTIFICATE_PROPERTIES_COL_NAME, _("Value"),
788 					    CERTIFICATE_PROPERTIES_COL_VALUE, hex_buffer, -1);
789 			g_free(hex_buffer);
790 			break;
791 		}
792 	}
793 }
794 
__certificate_properties_fill_cert_ext_BasicConstraints(GtkTreeStore * store,GtkTreeIter * parent,gnutls_x509_crt_t * certificate)795 void __certificate_properties_fill_cert_ext_BasicConstraints (GtkTreeStore *store,
796 									       GtkTreeIter *parent,
797 									       gnutls_x509_crt_t *certificate)
798 {
799 	guint critical;
800 	gint result;
801 	gint ca;
802 	gint path_len_constraint;
803 	gchar *pathlen_as_string = NULL;
804 	GtkTreeIter l;
805         gchar *ca_as_string = NULL;
806 
807 	result = gnutls_x509_crt_get_basic_constraints(*certificate, &critical, &ca, &path_len_constraint);
808 
809 	if (result < 0)	{
810 		fprintf(stderr, "Error: %s\n", gnutls_strerror(result));
811 		return;
812 	}
813 
814 	ca_as_string = ca ? _("TRUE") : _("FALSE");
815 
816 	pathlen_as_string = g_strdup_printf ("%d", path_len_constraint);
817 
818 	gtk_tree_store_append(store, &l, parent);
819 	gtk_tree_store_set(store, &l, CERTIFICATE_PROPERTIES_COL_NAME, _("CA"),
820 			   CERTIFICATE_PROPERTIES_COL_VALUE, ca_as_string, -1);
821 
822 	gtk_tree_store_append(store, &l, parent);
823 	gtk_tree_store_set(store, &l, CERTIFICATE_PROPERTIES_COL_NAME, _("Path Length Constraint"),
824 			   CERTIFICATE_PROPERTIES_COL_VALUE, pathlen_as_string, -1);
825 
826 	g_free (pathlen_as_string);
827 }
828 
__certificate_properties_fill_cert_ext_CRLDistributionPoints(GtkTreeStore * store,GtkTreeIter * parent,gnutls_x509_crt_t * certificate)829 void __certificate_properties_fill_cert_ext_CRLDistributionPoints (GtkTreeStore *store,
830 										    GtkTreeIter *parent,
831 										    gnutls_x509_crt_t *certificate)
832 {
833 	gint i;
834 	for (i = 0;; i++)
835 	{
836 		gint result;
837 		guint critical;
838 		const gint BUFFER_SIZE_MAX = 1024;
839 		gchar buffer[BUFFER_SIZE_MAX];
840 		gsize buffer_size = BUFFER_SIZE_MAX;
841 		gchar *hex_buffer;
842 		GtkTreeIter l;
843 
844 		result = gnutls_x509_crt_get_crl_dist_points(*certificate, i, buffer, &buffer_size, 0, &critical);
845 		if (result == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
846 			break;
847 
848 		if (result == GNUTLS_E_SHORT_MEMORY_BUFFER) {
849 			fprintf(stderr, "Error: (%s,%d): %s\n", __FILE__, __LINE__, gnutls_strerror(result));
850 			break;
851 		}
852 
853 		if (result < 0)	{
854 			fprintf(stderr, "Error: (%s,%d): %s\n", __FILE__, __LINE__, gnutls_strerror(result));
855 			break;
856 		}
857 
858 		switch (result)	{
859 		case GNUTLS_SAN_DNSNAME:
860 			gtk_tree_store_append(store, &l, parent);
861 			gtk_tree_store_set(store, &l, CERTIFICATE_PROPERTIES_COL_NAME, _("DNS Name"),
862 					   CERTIFICATE_PROPERTIES_COL_VALUE, buffer, -1);
863 			break;
864 		case GNUTLS_SAN_RFC822NAME:
865 			gtk_tree_store_append(store, &l, parent);
866 			gtk_tree_store_set(store, &l, CERTIFICATE_PROPERTIES_COL_NAME, _("RFC822 Name"),
867 					   CERTIFICATE_PROPERTIES_COL_VALUE, buffer, -1);
868 			break;
869 		case GNUTLS_SAN_URI:
870 			gtk_tree_store_append(store, &l, parent);
871 			gtk_tree_store_set(store, &l, CERTIFICATE_PROPERTIES_COL_NAME, _("URI"),
872 					   CERTIFICATE_PROPERTIES_COL_VALUE, buffer, -1);
873 			break;
874 		case GNUTLS_SAN_IPADDRESS:
875 			hex_buffer = __certificate_properties_dump_raw_data ((guchar *) buffer, buffer_size);
876 			gtk_tree_store_append(store, &l, parent);
877 			gtk_tree_store_set(store, &l, CERTIFICATE_PROPERTIES_COL_NAME, _("IP Address"),
878 					   CERTIFICATE_PROPERTIES_COL_VALUE, hex_buffer, -1);
879 			g_free(hex_buffer);
880 			break;
881 		case GNUTLS_SAN_DN:
882 			hex_buffer = __certificate_properties_dump_RDNSequence (buffer, buffer_size);
883 			gtk_tree_store_append(store, &l, parent);
884 			gtk_tree_store_set(store, &l, CERTIFICATE_PROPERTIES_COL_NAME, _("Directory Name"),
885 					   CERTIFICATE_PROPERTIES_COL_VALUE, hex_buffer, -1);
886 			g_free(hex_buffer);
887 			break;
888 		default:
889 			hex_buffer = __certificate_properties_dump_raw_data((guchar *) buffer, buffer_size);
890 			gtk_tree_store_append(store, &l, parent);
891 			gtk_tree_store_set(store, &l, CERTIFICATE_PROPERTIES_COL_NAME, _("Value"),
892 					   CERTIFICATE_PROPERTIES_COL_VALUE, hex_buffer, -1);
893 			g_free(hex_buffer);
894 			break;
895 		}
896 	}
897 }
898 
__certificate_properties_fill_cert_ext_AuthorityKeyIdentifier(GtkTreeStore * store,GtkTreeIter * parent,gnutls_x509_crt_t * certificate)899 void __certificate_properties_fill_cert_ext_AuthorityKeyIdentifier (GtkTreeStore *store,
900 										     GtkTreeIter *parent,
901 										     gnutls_x509_crt_t *certificate)
902 {
903 	gint result;
904 	guint critical;
905 	const gint BUFFER_SIZE_MAX = 256;
906 	gchar buffer[BUFFER_SIZE_MAX];
907 	gsize buffer_size = BUFFER_SIZE_MAX;
908 	gchar *hex_buffer = NULL;
909 	GtkTreeIter l;
910 
911 	result = gnutls_x509_crt_get_authority_key_id(*certificate, buffer, &buffer_size, &critical);
912 	if (result < 0) {
913 		fprintf(stderr, "Error: %s\n", gnutls_strerror(result));
914 		return;
915 	}
916 	hex_buffer = __certificate_properties_dump_raw_data((guchar *) buffer, buffer_size);
917 
918 	gtk_tree_store_append(store, &l, parent);
919 	gtk_tree_store_set(store, &l, CERTIFICATE_PROPERTIES_COL_NAME, _("Value"),
920 			   CERTIFICATE_PROPERTIES_COL_VALUE, hex_buffer, -1);
921 
922 	g_free(hex_buffer);
923 }
924 
__certificate_properties_fill_cert_ext_ExtKeyUsage(GtkTreeStore * store,GtkTreeIter * parent,gnutls_x509_crt_t * certificate)925 void __certificate_properties_fill_cert_ext_ExtKeyUsage (GtkTreeStore *store,
926 									  GtkTreeIter *parent,
927 									  gnutls_x509_crt_t *certificate)
928 {
929 	gint i;
930 	const gint BUFFER_SIZE_MAX = 1024;
931 	gchar usage_buffer[BUFFER_SIZE_MAX];
932 	gchar *usage_buffer_iterator = usage_buffer;
933 	GtkTreeIter l;
934 
935 	for (i = 0;; i++) {
936 		gint result;
937 		gchar buffer[BUFFER_SIZE_MAX];
938 		gsize buffer_size = BUFFER_SIZE_MAX;
939                 const gchar *label = NULL;
940 		result = gnutls_x509_crt_get_key_purpose_oid(*certificate, i, buffer, &buffer_size, 0);
941 
942 		if (result == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
943 			break;
944 		}
945 		if (result == GNUTLS_E_SHORT_MEMORY_BUFFER) {
946 			fprintf(stderr, "Error: (%s,%d): %s\n", __FILE__, __LINE__, gnutls_strerror(result));
947 			return;
948 		}
949 		if (result < 0) {
950 			fprintf(stderr, "Error: (%s,%d): %s\n", __FILE__, __LINE__, gnutls_strerror(result));
951 			return;
952 		}
953 		label = __certificate_properties_lookup_oid_label(certificate_properties_oid_label_table, buffer);
954 		usage_buffer_iterator += sprintf(usage_buffer_iterator, "%s\n", label);
955 	}
956 
957 	*(usage_buffer_iterator - 1) = 0;
958 	gtk_tree_store_append(store, &l, parent);
959 	gtk_tree_store_set(store, &l, CERTIFICATE_PROPERTIES_COL_NAME, _("Value"),
960 			   CERTIFICATE_PROPERTIES_COL_VALUE, usage_buffer, -1);
961 }
962 
__certificate_properties_fill_cert_ext(GtkTreeStore * store,GtkTreeIter * parent,gnutls_x509_crt_t * certificate)963 void __certificate_properties_fill_cert_ext (GtkTreeStore *store,
964 							      GtkTreeIter *parent,
965 							      gnutls_x509_crt_t *certificate)
966 {
967 	gint result;
968 	const gint OID_SIZE_MAX = 128;
969 	gchar oid[OID_SIZE_MAX];
970 	gsize oid_size = OID_SIZE_MAX;
971 	gint critical;
972 	guint i;
973 	GtkTreeIter j;
974 	GtkTreeIter k;
975 	GtkTreeIter l;
976 
977 	for (i = 0;; i++) {
978                 const gchar *label = NULL;
979                 const gchar *critical_as_string = NULL;
980 		certificate_properties_fill_t function;
981 
982 		oid_size = OID_SIZE_MAX;
983 		result = gnutls_x509_crt_get_extension_info(*certificate, i, oid, &oid_size, &critical);
984 		if (result == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
985 			break;
986 		if (result < 0)	{
987 			fprintf(stderr, "Error: %s\n", gnutls_strerror(result));
988 			break;
989 		}
990 		if (i == 0) {
991 			gtk_tree_store_append(store, &j, parent);
992 			gtk_tree_store_set(store, &j, CERTIFICATE_PROPERTIES_COL_NAME, _("Extensions"), -1);
993 		}
994 		label = __certificate_properties_lookup_oid_label(certificate_properties_oid_label_table, oid);
995 		gtk_tree_store_append(store, &k, &j);
996 		if (!label)
997 			label = oid;
998 		gtk_tree_store_set(store, &k, CERTIFICATE_PROPERTIES_COL_NAME, label, -1);
999 		critical_as_string = critical ? _("TRUE") : _("FALSE");
1000 		gtk_tree_store_append(store, &l, &k);
1001 		gtk_tree_store_set(store, &l, CERTIFICATE_PROPERTIES_COL_NAME, _("Critical"),
1002 				   CERTIFICATE_PROPERTIES_COL_VALUE, critical_as_string, -1);
1003 		function = __certificate_properties_lookup_oid_function(certificate_properties_oid_function_table, oid);
1004 		if (function)
1005 			function(store, &k, certificate);
1006 		else {
1007 			gint result;
1008 			const gint BUFFER_SIZE_MAX = 1024;
1009 			gchar buffer[BUFFER_SIZE_MAX];
1010 			gsize buffer_size = BUFFER_SIZE_MAX;
1011                         gchar *hex_buffer = NULL;
1012 
1013 			result = gnutls_x509_crt_get_extension_data(*certificate, i, buffer, &buffer_size);
1014 			hex_buffer = __certificate_properties_dump_raw_data((unsigned char *) buffer, buffer_size);
1015 			gtk_tree_store_append(store, &l, &k);
1016 			gtk_tree_store_set(store, &l, CERTIFICATE_PROPERTIES_COL_NAME, _("Value"),
1017 					   CERTIFICATE_PROPERTIES_COL_VALUE, hex_buffer, -1);
1018 			g_free(hex_buffer);
1019 		}
1020 	}
1021 }
1022 
__certificate_properties_fill_cert(GtkTreeStore * store,GtkTreeIter * parent,gnutls_x509_crt_t * certificate)1023 void __certificate_properties_fill_cert (GtkTreeStore *store,
1024 						   GtkTreeIter *parent,
1025 						   gnutls_x509_crt_t *certificate)
1026 {
1027 	GtkTreeIter i;
1028 	gtk_tree_store_append(store, &i, parent);
1029 	gtk_tree_store_set(store, &i, CERTIFICATE_PROPERTIES_COL_NAME, _("Certificate"), -1);
1030 	__certificate_properties_fill_cert_version(store, &i, certificate);
1031 	__certificate_properties_fill_cert_serialNumber(store, &i, certificate);
1032 	__certificate_properties_fill_cert_signature(store, &i, certificate);
1033 	__certificate_properties_fill_cert_issuer(store, &i, certificate);
1034 	__certificate_properties_fill_cert_validity(store, &i, certificate);
1035 	__certificate_properties_fill_cert_subject(store, &i, certificate);
1036 	__certificate_properties_fill_cert_subjectPublicKeyInfo(store, &i, certificate);
1037 	__certificate_properties_fill_cert_issuerUniqueID(store, &i, certificate);
1038 	__certificate_properties_fill_cert_subjectUniqueID(store, &i, certificate);
1039 	__certificate_properties_fill_cert_ext(store, &i, certificate);
1040 }
1041 
__certificate_properties_fill_signatureAlgorithm(GtkTreeStore * store,GtkTreeIter * parent,gnutls_x509_crt_t * certificate)1042 void __certificate_properties_fill_signatureAlgorithm (GtkTreeStore *store,
1043 						       GtkTreeIter *parent,
1044 						       gnutls_x509_crt_t *certificate)
1045 {
1046 	GtkTreeIter i;
1047 	gint result;
1048         const gchar *name = NULL;
1049 	GtkTreeIter j;
1050 
1051 	gtk_tree_store_append(store, &i, parent);
1052 	result = gnutls_x509_crt_get_signature_algorithm(*certificate);
1053 	name = gnutls_sign_algorithm_get_name(result);
1054 	gtk_tree_store_set(store, &i, CERTIFICATE_PROPERTIES_COL_NAME, _("Signature Algorithm"), -1);
1055 	gtk_tree_store_append(store, &j, &i);
1056 	gtk_tree_store_set(store, &j, CERTIFICATE_PROPERTIES_COL_NAME, _("Algorithm"),
1057 			   CERTIFICATE_PROPERTIES_COL_VALUE, name, -1);
1058 	gtk_tree_store_append(store, &j, &i);
1059 	gtk_tree_store_set(store, &j, CERTIFICATE_PROPERTIES_COL_NAME, _("Parameters"),
1060 			   CERTIFICATE_PROPERTIES_COL_VALUE, _("(unknown)"), -1);
1061 }
1062 
__certificate_properties_fill_signatureValue(GtkTreeStore * store,GtkTreeIter * parent,gnutls_x509_crt_t * certificate)1063 void __certificate_properties_fill_signatureValue (GtkTreeStore *store, GtkTreeIter *parent, gnutls_x509_crt_t *certificate)
1064 {
1065 	GtkTreeIter i;
1066 	gint result;
1067 	gchar *buffer = NULL;
1068 	gsize buffer_size = 0;
1069 	gchar *hex_buffer = NULL;
1070 
1071 	gtk_tree_store_append(store, &i, parent);
1072 
1073 	result = gnutls_x509_crt_get_signature(*certificate, 0, &buffer_size);
1074 	if (result != GNUTLS_E_SHORT_MEMORY_BUFFER) {
1075 		fprintf(stderr, "Error: (%s,%d): %s\n", __FILE__, __LINE__, gnutls_strerror(result));
1076 		return;
1077 	}
1078 
1079 	buffer = g_new0 (gchar, buffer_size);
1080 
1081 	result = gnutls_x509_crt_get_signature(*certificate, buffer, &buffer_size);
1082 	if (result < 0) {
1083 		fprintf(stderr, "Error: (%s,%d): %s\n", __FILE__, __LINE__, gnutls_strerror(result));
1084 		return;
1085 	}
1086 
1087 	hex_buffer = __certificate_properties_dump_raw_data((guchar *) buffer, buffer_size);
1088 
1089 	gtk_tree_store_set(store, &i, CERTIFICATE_PROPERTIES_COL_NAME, _("Signature"),
1090 			   CERTIFICATE_PROPERTIES_COL_VALUE, hex_buffer, -1);
1091 
1092 	g_free(hex_buffer);
1093 }
1094 
__certificate_properties_fill_certificate(GtkTreeStore * store,gnutls_x509_crt_t * certificate)1095 void __certificate_properties_fill_certificate(GtkTreeStore *store, gnutls_x509_crt_t *certificate)
1096 {
1097 	__certificate_properties_fill_cert(store, 0, certificate);
1098 	__certificate_properties_fill_signatureAlgorithm(store, 0, certificate);
1099 	__certificate_properties_fill_signatureValue(store, 0, certificate);
1100 }
1101 
1102 void
__certificate_details_populate(const char * certificate_pem)1103 __certificate_details_populate(const char *certificate_pem)
1104 {
1105 	gint result;
1106 	gnutls_datum_t pem_datum;
1107 	gnutls_x509_crt_t certificate;
1108 	GtkTreeStore *store = NULL;
1109 	GObject *view = NULL;
1110 	GtkCellRenderer *renderer = NULL;
1111 
1112 	pem_datum.data = (guchar *) certificate_pem;
1113 	pem_datum.size = strlen(certificate_pem);
1114 	result = gnutls_x509_crt_init(&certificate);
1115 
1116 	if (result < 0)
1117 	{
1118 		fprintf(stderr, "Error: (%s,%d): %s\n", __FILE__, __LINE__, gnutls_strerror(result));
1119 		return;
1120 	}
1121 
1122 	gnutls_x509_crt_import(certificate, &pem_datum, GNUTLS_X509_FMT_PEM);
1123 	if (result < 0)
1124 	{
1125 		fprintf(stderr, "Error: (%s,%d): %s\n", __FILE__, __LINE__, gnutls_strerror(result));
1126 		return;
1127 	}
1128 
1129 	store = gtk_tree_store_new(CERTIFICATE_PROPERTIES_N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING);
1130 	__certificate_properties_fill_certificate(store, &certificate);
1131 	gnutls_x509_crt_deinit(certificate);
1132 
1133 	view = gtk_builder_get_object(certificate_properties_window_gtkb, "certTreeView");
1134 	renderer = gtk_cell_renderer_text_new();
1135 
1136 	g_object_set(renderer, "yalign", 0.0, NULL);
1137 	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view), -1, _("Name"), renderer, "text", CERTIFICATE_PROPERTIES_COL_NAME, NULL);
1138 	renderer = gtk_cell_renderer_text_new();
1139 
1140 	g_object_set(renderer, "family", "Monospace", "family-set", 1, NULL);
1141 	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view), -1, _("Value"), renderer, "text", CERTIFICATE_PROPERTIES_COL_VALUE, NULL);
1142 	gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(store));
1143 
1144 	g_object_unref(store);
1145 }
1146 
1147 #if 0
1148 
1149 //Function included for generating extra gettext strings. Do not remove.
1150 
1151 void useless_function ()
1152 {
1153 	printf ("%s",_("TLS WWW Server"));
1154 	printf ("%s",_("TLS WWW Client"));
1155 	printf ("%s",_("Code signing"));
1156 	printf ("%s",_("Email protection"));
1157 	printf ("%s",_("Time stamping"));
1158 	printf ("%s",_("OCSP signing"));
1159 	printf ("%s",_("Any purpose"));
1160 	printf ("%s",_("Subject Directory Attributes"));
1161 	printf ("%s",_("Subject Key Identifier"));
1162 	printf ("%s",_("Key Usage"));
1163 	printf ("%s",_("Private Key Usage Period"));
1164 	printf ("%s",_("Subject Alternative Name"));
1165 	printf ("%s",_("Basic Constraints"));
1166 	printf ("%s",_("Name Constraints"));
1167 	printf ("%s",_("CRL Distribution Points"));
1168 	printf ("%s",_("Certificate Policies"));
1169 	printf ("%s",_("Policy Mappings"));
1170 	printf ("%s",_("Authority Key Identifier"));
1171 	printf ("%s",_("Policy Constraints"));
1172 	printf ("%s",_("Extended Key Usage"));
1173 	printf ("%s",_("Delta CRL Distribution Point"));
1174 	printf ("%s",_("Inhibit Any-Policy"));
1175 
1176 }
1177 
1178 #endif
1179