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. */
33 #define _(String) dgettext (PACKAGE, String)
35 #define addf _gnutls_buffer_append_printf
36 #define adds _gnutls_buffer_append_str
39 print_key_usage (gnutls_buffer_st
* str
, gnutls_openpgp_crt_t cert
,
42 unsigned int key_usage
;
45 adds (str
, _("\t\tKey Usage:\n"));
48 if (idx
== (unsigned int) -1)
49 err
= gnutls_openpgp_crt_get_key_usage (cert
, &key_usage
);
51 err
= gnutls_openpgp_crt_get_subkey_usage (cert
, idx
, &key_usage
);
54 addf (str
, _("error: get_key_usage: %s\n"), gnutls_strerror (err
));
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.
74 print_key_id (gnutls_buffer_st
* str
, gnutls_openpgp_crt_t cert
, int idx
)
76 gnutls_openpgp_keyid_t id
;
80 err
= gnutls_openpgp_crt_get_key_id (cert
, id
);
82 err
= gnutls_openpgp_crt_get_subkey_id (cert
, idx
, id
);
85 addf (str
, "error: get_key_id: %s\n", gnutls_strerror (err
));
88 adds (str
, _("\tID (hex): "));
89 _gnutls_buffer_hexprint (str
, id
, sizeof (id
));
95 /* idx == -1 indicates main key
96 * otherwise the subkey.
99 print_key_fingerprint (gnutls_buffer_st
* str
, gnutls_openpgp_crt_t cert
)
102 size_t fpr_size
= sizeof (fpr
);
108 err
= gnutls_openpgp_crt_get_fingerprint (cert
, fpr
, &fpr_size
);
110 addf (str
, "error: get_fingerprint: %s\n", gnutls_strerror (err
));
113 adds (str
, _("\tFingerprint (hex): "));
114 _gnutls_buffer_hexprint (str
, fpr
, fpr_size
);
118 err
= gnutls_openpgp_crt_get_pk_algorithm (cert
, &bits
);
122 name
= gnutls_pk_get_name(err
);
126 p
= _gnutls_key_fingerprint_randomart(fpr
, fpr_size
, name
, bits
, "\t\t");
130 adds (str
, _("\tFingerprint's random art:\n"));
138 print_key_revoked (gnutls_buffer_st
* str
, gnutls_openpgp_crt_t cert
, int idx
)
143 err
= gnutls_openpgp_crt_get_revoked_status (cert
);
145 err
= gnutls_openpgp_crt_get_subkey_revoked_status (cert
, idx
);
148 adds (str
, _("\tRevoked: True\n"));
150 adds (str
, _("\tRevoked: False\n"));
154 print_key_times (gnutls_buffer_st
* str
, gnutls_openpgp_crt_t cert
, int idx
)
158 adds (str
, _("\tTime stamps:\n"));
161 tim
= gnutls_openpgp_crt_get_creation_time (cert
);
163 tim
= gnutls_openpgp_crt_get_subkey_creation_time (cert
, idx
);
167 size_t max
= sizeof (s
);
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
);
175 addf (str
, _("\t\tCreation: %s\n"), s
);
179 tim
= gnutls_openpgp_crt_get_expiration_time (cert
);
181 tim
= gnutls_openpgp_crt_get_subkey_expiration_time (cert
, idx
);
184 size_t max
= sizeof (s
);
189 adds (str
, _("\t\tExpiration: Never\n"));
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
);
198 addf (str
, _("\t\tExpiration: %s\n"), s
);
204 print_key_info (gnutls_buffer_st
* str
, gnutls_openpgp_crt_t cert
, int idx
)
210 err
= gnutls_openpgp_crt_get_pk_algorithm (cert
, &bits
);
212 err
= gnutls_openpgp_crt_get_subkey_pk_algorithm (cert
, idx
, &bits
);
215 addf (str
, "error: get_pk_algorithm: %s\n", gnutls_strerror (err
));
218 const char *name
= gnutls_pk_algorithm_get_name (err
);
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
234 err
= gnutls_openpgp_crt_get_pk_rsa_raw (cert
, &m
, &e
);
237 gnutls_openpgp_crt_get_subkey_pk_rsa_raw (cert
, idx
, &m
, &e
);
240 addf (str
, "error: get_pk_rsa_raw: %s\n",
241 gnutls_strerror (err
));
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
);
258 gnutls_datum_t p
, q
, g
, y
;
261 err
= gnutls_openpgp_crt_get_pk_dsa_raw (cert
, &p
, &q
, &g
, &y
);
264 gnutls_openpgp_crt_get_subkey_pk_dsa_raw (cert
, idx
, &p
, &q
,
267 addf (str
, "error: get_pk_dsa_raw: %s\n",
268 gnutls_strerror (err
));
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
);
295 print_cert (gnutls_buffer_st
* str
, gnutls_openpgp_crt_t cert
)
300 print_key_revoked (str
, cert
, -1);
304 int version
= gnutls_openpgp_crt_get_version (cert
);
306 addf (str
, "error: get_version: %s\n", gnutls_strerror (version
));
308 addf (str
, _("\tVersion: %d\n"), version
);
312 print_key_id (str
, cert
, -1);
314 print_key_fingerprint (str
, cert
);
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
));
330 dn
= gnutls_malloc (dn_size
);
332 addf (str
, "error: malloc (%d): %s\n", (int) dn_size
,
333 gnutls_strerror (GNUTLS_E_MEMORY_ERROR
));
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
));
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
);
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
);
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
);
376 print_oneline (gnutls_buffer_st
* str
, gnutls_openpgp_crt_t cert
)
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
));
393 dn
= gnutls_malloc (dn_size
);
395 addf (str
, "unknown name (%s), ",
396 gnutls_strerror (GNUTLS_E_MEMORY_ERROR
));
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
));
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
);
418 size_t fpr_size
= sizeof (fpr
);
421 err
= gnutls_openpgp_crt_get_fingerprint (cert
, fpr
, &fpr_size
);
423 addf (str
, "error: get_fingerprint: %s\n", gnutls_strerror (err
));
426 adds (str
, _("fingerprint: "));
427 _gnutls_buffer_hexprint (str
, fpr
, fpr_size
);
435 tim
= gnutls_openpgp_crt_get_creation_time (cert
);
438 size_t max
= sizeof (s
);
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
);
446 addf (str
, _("created: %s, "), s
);
449 tim
= gnutls_openpgp_crt_get_expiration_time (cert
);
452 size_t max
= sizeof (s
);
456 adds (str
, _("never expires, "));
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
);
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
);
476 addf (str
, _("key algorithm %s (%d bits)"), algostr
, bits
);
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
;
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
);
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
--;