Simplified certificate verification by adding gnutls_certificate_verify_peers3().
[gnutls.git] / lib / openpgp / output.c
blob88f522db70782613b4d3d796f044c418dddfb0d7
1 /*
2 * Copyright (C) 2007-2012 Free Software Foundation, Inc.
4 * Author: Simon Josefsson, Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
8 * The GnuTLS is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 3 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
23 /* Functions for printing X.509 Certificate structures
26 #include <gnutls_int.h>
27 #include <gnutls/openpgp.h>
28 #include <gnutls_errors.h>
29 #include <extras/randomart.h>
31 /* I18n of error codes. */
32 #include "gettext.h"
33 #define _(String) dgettext (PACKAGE, String)
35 #define addf _gnutls_buffer_append_printf
36 #define adds _gnutls_buffer_append_str
38 static void
39 print_key_usage (gnutls_buffer_st * str, gnutls_openpgp_crt_t cert,
40 unsigned int idx)
42 unsigned int key_usage;
43 int err;
45 adds (str, _("\t\tKey Usage:\n"));
48 if (idx == (unsigned int) -1)
49 err = gnutls_openpgp_crt_get_key_usage (cert, &key_usage);
50 else
51 err = gnutls_openpgp_crt_get_subkey_usage (cert, idx, &key_usage);
52 if (err < 0)
54 addf (str, _("error: get_key_usage: %s\n"), gnutls_strerror (err));
55 return;
58 if (key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE)
59 adds (str, _("\t\t\tDigital signatures.\n"));
60 if (key_usage & GNUTLS_KEY_KEY_ENCIPHERMENT)
61 adds (str, _("\t\t\tCommunications encipherment.\n"));
62 if (key_usage & GNUTLS_KEY_DATA_ENCIPHERMENT)
63 adds (str, _("\t\t\tStorage data encipherment.\n"));
64 if (key_usage & GNUTLS_KEY_KEY_AGREEMENT)
65 adds (str, _("\t\t\tAuthentication.\n"));
66 if (key_usage & GNUTLS_KEY_KEY_CERT_SIGN)
67 adds (str, _("\t\t\tCertificate signing.\n"));
70 /* idx == -1 indicates main key
71 * otherwise the subkey.
73 static void
74 print_key_id (gnutls_buffer_st * str, gnutls_openpgp_crt_t cert, int idx)
76 gnutls_openpgp_keyid_t id;
77 int err;
79 if (idx < 0)
80 err = gnutls_openpgp_crt_get_key_id (cert, id);
81 else
82 err = gnutls_openpgp_crt_get_subkey_id (cert, idx, id);
84 if (err < 0)
85 addf (str, "error: get_key_id: %s\n", gnutls_strerror (err));
86 else
88 adds (str, _("\tID (hex): "));
89 _gnutls_buffer_hexprint (str, id, sizeof (id));
90 addf (str, "\n");
95 /* idx == -1 indicates main key
96 * otherwise the subkey.
98 static void
99 print_key_fingerprint (gnutls_buffer_st * str, gnutls_openpgp_crt_t cert)
101 uint8_t fpr[128];
102 size_t fpr_size = sizeof (fpr);
103 int err;
104 const char* name;
105 char* p;
106 unsigned int bits;
108 err = gnutls_openpgp_crt_get_fingerprint (cert, fpr, &fpr_size);
109 if (err < 0)
110 addf (str, "error: get_fingerprint: %s\n", gnutls_strerror (err));
111 else
113 adds (str, _("\tFingerprint (hex): "));
114 _gnutls_buffer_hexprint (str, fpr, fpr_size);
115 addf (str, "\n");
118 err = gnutls_openpgp_crt_get_pk_algorithm (cert, &bits);
119 if (err < 0)
120 return;
122 name = gnutls_pk_get_name(err);
123 if (name == NULL)
124 return;
126 p = _gnutls_key_fingerprint_randomart(fpr, fpr_size, name, bits, "\t\t");
127 if (p == NULL)
128 return;
130 adds (str, _("\tFingerprint's random art:\n"));
131 adds (str, p);
132 adds (str, "\n");
134 gnutls_free(p);
137 static void
138 print_key_revoked (gnutls_buffer_st * str, gnutls_openpgp_crt_t cert, int idx)
140 int err;
142 if (idx < 0)
143 err = gnutls_openpgp_crt_get_revoked_status (cert);
144 else
145 err = gnutls_openpgp_crt_get_subkey_revoked_status (cert, idx);
147 if (err != 0)
148 adds (str, _("\tRevoked: True\n"));
149 else
150 adds (str, _("\tRevoked: False\n"));
153 static void
154 print_key_times (gnutls_buffer_st * str, gnutls_openpgp_crt_t cert, int idx)
156 time_t tim;
158 adds (str, _("\tTime stamps:\n"));
160 if (idx == -1)
161 tim = gnutls_openpgp_crt_get_creation_time (cert);
162 else
163 tim = gnutls_openpgp_crt_get_subkey_creation_time (cert, idx);
166 char s[42];
167 size_t max = sizeof (s);
168 struct tm t;
170 if (gmtime_r (&tim, &t) == NULL)
171 addf (str, "error: gmtime_r (%ld)\n", (unsigned long) tim);
172 else if (strftime (s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0)
173 addf (str, "error: strftime (%ld)\n", (unsigned long) tim);
174 else
175 addf (str, _("\t\tCreation: %s\n"), s);
178 if (idx == -1)
179 tim = gnutls_openpgp_crt_get_expiration_time (cert);
180 else
181 tim = gnutls_openpgp_crt_get_subkey_expiration_time (cert, idx);
183 char s[42];
184 size_t max = sizeof (s);
185 struct tm t;
187 if (tim == 0)
189 adds (str, _("\t\tExpiration: Never\n"));
191 else
193 if (gmtime_r (&tim, &t) == NULL)
194 addf (str, "error: gmtime_r (%ld)\n", (unsigned long) tim);
195 else if (strftime (s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0)
196 addf (str, "error: strftime (%ld)\n", (unsigned long) tim);
197 else
198 addf (str, _("\t\tExpiration: %s\n"), s);
203 static void
204 print_key_info (gnutls_buffer_st * str, gnutls_openpgp_crt_t cert, int idx)
206 int err;
207 unsigned int bits;
209 if (idx == -1)
210 err = gnutls_openpgp_crt_get_pk_algorithm (cert, &bits);
211 else
212 err = gnutls_openpgp_crt_get_subkey_pk_algorithm (cert, idx, &bits);
214 if (err < 0)
215 addf (str, "error: get_pk_algorithm: %s\n", gnutls_strerror (err));
216 else
218 const char *name = gnutls_pk_algorithm_get_name (err);
219 if (name == NULL)
220 name = _("unknown");
222 addf (str, _("\tPublic Key Algorithm: %s\n"), name);
223 addf (str, _("\tKey Security Level: %s\n"),
224 gnutls_sec_param_get_name (gnutls_pk_bits_to_sec_param
225 (err, bits)));
227 switch (err)
229 case GNUTLS_PK_RSA:
231 gnutls_datum_t m, e;
233 if (idx == -1)
234 err = gnutls_openpgp_crt_get_pk_rsa_raw (cert, &m, &e);
235 else
236 err =
237 gnutls_openpgp_crt_get_subkey_pk_rsa_raw (cert, idx, &m, &e);
239 if (err < 0)
240 addf (str, "error: get_pk_rsa_raw: %s\n",
241 gnutls_strerror (err));
242 else
244 addf (str, _("\t\tModulus (bits %d):\n"), bits);
245 _gnutls_buffer_hexdump (str, m.data, m.size, "\t\t\t");
246 adds (str, _("\t\tExponent:\n"));
247 _gnutls_buffer_hexdump (str, e.data, e.size, "\t\t\t");
249 gnutls_free (m.data);
250 gnutls_free (e.data);
254 break;
256 case GNUTLS_PK_DSA:
258 gnutls_datum_t p, q, g, y;
260 if (idx == -1)
261 err = gnutls_openpgp_crt_get_pk_dsa_raw (cert, &p, &q, &g, &y);
262 else
263 err =
264 gnutls_openpgp_crt_get_subkey_pk_dsa_raw (cert, idx, &p, &q,
265 &g, &y);
266 if (err < 0)
267 addf (str, "error: get_pk_dsa_raw: %s\n",
268 gnutls_strerror (err));
269 else
271 addf (str, _("\t\tPublic key (bits %d):\n"), bits);
272 _gnutls_buffer_hexdump (str, y.data, y.size, "\t\t\t");
273 adds (str, _("\t\tP:\n"));
274 _gnutls_buffer_hexdump (str, p.data, p.size, "\t\t\t");
275 adds (str, _("\t\tQ:\n"));
276 _gnutls_buffer_hexdump (str, q.data, q.size, "\t\t\t");
277 adds (str, _("\t\tG:\n"));
278 _gnutls_buffer_hexdump (str, g.data, g.size, "\t\t\t");
280 gnutls_free (p.data);
281 gnutls_free (q.data);
282 gnutls_free (g.data);
283 gnutls_free (y.data);
286 break;
288 default:
289 break;
294 static void
295 print_cert (gnutls_buffer_st * str, gnutls_openpgp_crt_t cert)
297 int i, subkeys;
298 int err;
300 print_key_revoked (str, cert, -1);
302 /* Version. */
304 int version = gnutls_openpgp_crt_get_version (cert);
305 if (version < 0)
306 addf (str, "error: get_version: %s\n", gnutls_strerror (version));
307 else
308 addf (str, _("\tVersion: %d\n"), version);
311 /* ID. */
312 print_key_id (str, cert, -1);
314 print_key_fingerprint (str, cert);
316 /* Names. */
317 i = 0;
320 char *dn;
321 size_t dn_size = 0;
323 err = gnutls_openpgp_crt_get_name (cert, i, NULL, &dn_size);
324 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER
325 && err != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
326 && err != GNUTLS_E_OPENPGP_UID_REVOKED)
327 addf (str, "error: get_name: %s\n", gnutls_strerror (err));
328 else
330 dn = gnutls_malloc (dn_size);
331 if (!dn)
332 addf (str, "error: malloc (%d): %s\n", (int) dn_size,
333 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
334 else
336 err = gnutls_openpgp_crt_get_name (cert, i, dn, &dn_size);
337 if (err < 0 && err != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE &&
338 err != GNUTLS_E_OPENPGP_UID_REVOKED)
339 addf (str, "error: get_name: %s\n", gnutls_strerror (err));
340 else if (err >= 0)
341 addf (str, _("\tName[%d]: %s\n"), i, dn);
342 else if (err == GNUTLS_E_OPENPGP_UID_REVOKED)
343 addf (str, _("\tRevoked Name[%d]: %s\n"), i, dn);
345 gnutls_free (dn);
349 i++;
351 while (err >= 0);
353 print_key_times (str, cert, -1);
355 print_key_info (str, cert, -1);
356 print_key_usage (str, cert, -1);
358 subkeys = gnutls_openpgp_crt_get_subkey_count (cert);
359 if (subkeys < 0)
360 return;
362 for (i = 0; i < subkeys; i++)
364 addf (str, _("\n\tSubkey[%d]:\n"), i);
366 print_key_revoked (str, cert, i);
367 print_key_id (str, cert, i);
368 print_key_times (str, cert, i);
369 print_key_info (str, cert, i);
370 print_key_usage (str, cert, i);
375 static void
376 print_oneline (gnutls_buffer_st * str, gnutls_openpgp_crt_t cert)
378 int err, i;
380 i = 0;
383 char *dn;
384 size_t dn_size = 0;
386 err = gnutls_openpgp_crt_get_name (cert, i, NULL, &dn_size);
387 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER
388 && err != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
389 && err != GNUTLS_E_OPENPGP_UID_REVOKED)
390 addf (str, "unknown name (%s), ", gnutls_strerror (err));
391 else
393 dn = gnutls_malloc (dn_size);
394 if (!dn)
395 addf (str, "unknown name (%s), ",
396 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
397 else
399 err = gnutls_openpgp_crt_get_name (cert, i, dn, &dn_size);
400 if (err < 0 && err != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE &&
401 err != GNUTLS_E_OPENPGP_UID_REVOKED)
402 addf (str, "unknown name (%s), ", gnutls_strerror (err));
403 else if (err >= 0)
404 addf (str, _("name[%d]: %s, "), i, dn);
405 else if (err == GNUTLS_E_OPENPGP_UID_REVOKED)
406 addf (str, _("revoked name[%d]: %s, "), i, dn);
408 gnutls_free (dn);
412 i++;
414 while (err >= 0);
417 char fpr[128];
418 size_t fpr_size = sizeof (fpr);
419 int err;
421 err = gnutls_openpgp_crt_get_fingerprint (cert, fpr, &fpr_size);
422 if (err < 0)
423 addf (str, "error: get_fingerprint: %s\n", gnutls_strerror (err));
424 else
426 adds (str, _("fingerprint: "));
427 _gnutls_buffer_hexprint (str, fpr, fpr_size);
428 addf (str, ", ");
433 time_t tim;
435 tim = gnutls_openpgp_crt_get_creation_time (cert);
437 char s[42];
438 size_t max = sizeof (s);
439 struct tm t;
441 if (gmtime_r (&tim, &t) == NULL)
442 addf (str, "error: gmtime_r (%ld), ", (unsigned long) tim);
443 else if (strftime (s, max, "%Y-%m-%d %H:%M:%S UTC", &t) == 0)
444 addf (str, "error: strftime (%ld), ", (unsigned long) tim);
445 else
446 addf (str, _("created: %s, "), s);
449 tim = gnutls_openpgp_crt_get_expiration_time (cert);
451 char s[42];
452 size_t max = sizeof (s);
453 struct tm t;
455 if (tim == 0)
456 adds (str, _("never expires, "));
457 else
459 if (gmtime_r (&tim, &t) == NULL)
460 addf (str, "error: gmtime_r (%ld), ", (unsigned long) tim);
461 else if (strftime (s, max, "%Y-%m-%d %H:%M:%S UTC", &t) == 0)
462 addf (str, "error: strftime (%ld), ", (unsigned long) tim);
463 else
464 addf (str, _("expires: %s, "), s);
470 unsigned int bits = 0;
471 gnutls_pk_algorithm_t algo =
472 gnutls_openpgp_crt_get_pk_algorithm (cert, &bits);
473 const char *algostr = gnutls_pk_algorithm_get_name (algo);
475 if (algostr)
476 addf (str, _("key algorithm %s (%d bits)"), algostr, bits);
477 else
478 addf (str, _("unknown key algorithm (%d)"), algo);
483 * gnutls_openpgp_crt_print:
484 * @cert: The structure to be printed
485 * @format: Indicate the format to use
486 * @out: Newly allocated datum with (0) terminated string.
488 * This function will pretty print an OpenPGP certificate, suitable
489 * for display to a human.
491 * The format should be (0) for future compatibility.
493 * The output @out needs to be deallocate using gnutls_free().
495 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
498 gnutls_openpgp_crt_print (gnutls_openpgp_crt_t cert,
499 gnutls_certificate_print_formats_t format,
500 gnutls_datum_t * out)
502 gnutls_buffer_st str;
503 int ret;
505 _gnutls_buffer_init (&str);
507 if (format == GNUTLS_CRT_PRINT_ONELINE)
508 print_oneline (&str, cert);
509 else if (format == GNUTLS_CRT_PRINT_COMPACT)
511 print_oneline (&str, cert);
513 _gnutls_buffer_append_data (&str, "\n", 1);
514 print_key_fingerprint (&str, cert);
516 else
518 _gnutls_buffer_append_str (&str,
519 _("OpenPGP Certificate Information:\n"));
520 print_cert (&str, cert);
523 _gnutls_buffer_append_data (&str, "\0", 1);
525 ret = _gnutls_buffer_to_datum( &str, out);
526 if (out->size > 0) out->size--;
528 return ret;