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 #define addf _gnutls_buffer_append_printf
32 #define adds _gnutls_buffer_append_str
35 print_key_usage (gnutls_buffer_st
* str
, gnutls_openpgp_crt_t cert
,
38 unsigned int key_usage
;
41 adds (str
, _("\t\tKey Usage:\n"));
44 if (idx
== (unsigned int) -1)
45 err
= gnutls_openpgp_crt_get_key_usage (cert
, &key_usage
);
47 err
= gnutls_openpgp_crt_get_subkey_usage (cert
, idx
, &key_usage
);
50 addf (str
, _("error: get_key_usage: %s\n"), gnutls_strerror (err
));
54 if (key_usage
& GNUTLS_KEY_DIGITAL_SIGNATURE
)
55 adds (str
, _("\t\t\tDigital signatures.\n"));
56 if (key_usage
& GNUTLS_KEY_KEY_ENCIPHERMENT
)
57 adds (str
, _("\t\t\tCommunications encipherment.\n"));
58 if (key_usage
& GNUTLS_KEY_DATA_ENCIPHERMENT
)
59 adds (str
, _("\t\t\tStorage data encipherment.\n"));
60 if (key_usage
& GNUTLS_KEY_KEY_AGREEMENT
)
61 adds (str
, _("\t\t\tAuthentication.\n"));
62 if (key_usage
& GNUTLS_KEY_KEY_CERT_SIGN
)
63 adds (str
, _("\t\t\tCertificate signing.\n"));
66 /* idx == -1 indicates main key
67 * otherwise the subkey.
70 print_key_id (gnutls_buffer_st
* str
, gnutls_openpgp_crt_t cert
, int idx
)
72 gnutls_openpgp_keyid_t id
;
76 err
= gnutls_openpgp_crt_get_key_id (cert
, id
);
78 err
= gnutls_openpgp_crt_get_subkey_id (cert
, idx
, id
);
81 addf (str
, "error: get_key_id: %s\n", gnutls_strerror (err
));
84 adds (str
, _("\tID (hex): "));
85 _gnutls_buffer_hexprint (str
, id
, sizeof (id
));
91 /* idx == -1 indicates main key
92 * otherwise the subkey.
95 print_key_fingerprint (gnutls_buffer_st
* str
, gnutls_openpgp_crt_t cert
)
98 size_t fpr_size
= sizeof (fpr
);
104 err
= gnutls_openpgp_crt_get_fingerprint (cert
, fpr
, &fpr_size
);
106 addf (str
, "error: get_fingerprint: %s\n", gnutls_strerror (err
));
109 adds (str
, _("\tFingerprint (hex): "));
110 _gnutls_buffer_hexprint (str
, fpr
, fpr_size
);
114 err
= gnutls_openpgp_crt_get_pk_algorithm (cert
, &bits
);
118 name
= gnutls_pk_get_name(err
);
122 p
= _gnutls_key_fingerprint_randomart(fpr
, fpr_size
, name
, bits
, "\t\t");
126 adds (str
, _("\tFingerprint's random art:\n"));
134 print_key_revoked (gnutls_buffer_st
* str
, gnutls_openpgp_crt_t cert
, int idx
)
139 err
= gnutls_openpgp_crt_get_revoked_status (cert
);
141 err
= gnutls_openpgp_crt_get_subkey_revoked_status (cert
, idx
);
144 adds (str
, _("\tRevoked: True\n"));
146 adds (str
, _("\tRevoked: False\n"));
150 print_key_times (gnutls_buffer_st
* str
, gnutls_openpgp_crt_t cert
, int idx
)
154 adds (str
, _("\tTime stamps:\n"));
157 tim
= gnutls_openpgp_crt_get_creation_time (cert
);
159 tim
= gnutls_openpgp_crt_get_subkey_creation_time (cert
, idx
);
163 size_t max
= sizeof (s
);
166 if (gmtime_r (&tim
, &t
) == NULL
)
167 addf (str
, "error: gmtime_r (%ld)\n", (unsigned long) tim
);
168 else if (strftime (s
, max
, "%a %b %d %H:%M:%S UTC %Y", &t
) == 0)
169 addf (str
, "error: strftime (%ld)\n", (unsigned long) tim
);
171 addf (str
, _("\t\tCreation: %s\n"), s
);
175 tim
= gnutls_openpgp_crt_get_expiration_time (cert
);
177 tim
= gnutls_openpgp_crt_get_subkey_expiration_time (cert
, idx
);
180 size_t max
= sizeof (s
);
185 adds (str
, _("\t\tExpiration: Never\n"));
189 if (gmtime_r (&tim
, &t
) == NULL
)
190 addf (str
, "error: gmtime_r (%ld)\n", (unsigned long) tim
);
191 else if (strftime (s
, max
, "%a %b %d %H:%M:%S UTC %Y", &t
) == 0)
192 addf (str
, "error: strftime (%ld)\n", (unsigned long) tim
);
194 addf (str
, _("\t\tExpiration: %s\n"), s
);
200 print_key_info (gnutls_buffer_st
* str
, gnutls_openpgp_crt_t cert
, int idx
)
206 err
= gnutls_openpgp_crt_get_pk_algorithm (cert
, &bits
);
208 err
= gnutls_openpgp_crt_get_subkey_pk_algorithm (cert
, idx
, &bits
);
211 addf (str
, "error: get_pk_algorithm: %s\n", gnutls_strerror (err
));
214 const char *name
= gnutls_pk_algorithm_get_name (err
);
218 addf (str
, _("\tPublic Key Algorithm: %s\n"), name
);
219 addf (str
, _("\tKey Security Level: %s\n"),
220 gnutls_sec_param_get_name (gnutls_pk_bits_to_sec_param
230 err
= gnutls_openpgp_crt_get_pk_rsa_raw (cert
, &m
, &e
);
233 gnutls_openpgp_crt_get_subkey_pk_rsa_raw (cert
, idx
, &m
, &e
);
236 addf (str
, "error: get_pk_rsa_raw: %s\n",
237 gnutls_strerror (err
));
240 addf (str
, _("\t\tModulus (bits %d):\n"), bits
);
241 _gnutls_buffer_hexdump (str
, m
.data
, m
.size
, "\t\t\t");
242 adds (str
, _("\t\tExponent:\n"));
243 _gnutls_buffer_hexdump (str
, e
.data
, e
.size
, "\t\t\t");
245 gnutls_free (m
.data
);
246 gnutls_free (e
.data
);
254 gnutls_datum_t p
, q
, g
, y
;
257 err
= gnutls_openpgp_crt_get_pk_dsa_raw (cert
, &p
, &q
, &g
, &y
);
260 gnutls_openpgp_crt_get_subkey_pk_dsa_raw (cert
, idx
, &p
, &q
,
263 addf (str
, "error: get_pk_dsa_raw: %s\n",
264 gnutls_strerror (err
));
267 addf (str
, _("\t\tPublic key (bits %d):\n"), bits
);
268 _gnutls_buffer_hexdump (str
, y
.data
, y
.size
, "\t\t\t");
269 adds (str
, _("\t\tP:\n"));
270 _gnutls_buffer_hexdump (str
, p
.data
, p
.size
, "\t\t\t");
271 adds (str
, _("\t\tQ:\n"));
272 _gnutls_buffer_hexdump (str
, q
.data
, q
.size
, "\t\t\t");
273 adds (str
, _("\t\tG:\n"));
274 _gnutls_buffer_hexdump (str
, g
.data
, g
.size
, "\t\t\t");
276 gnutls_free (p
.data
);
277 gnutls_free (q
.data
);
278 gnutls_free (g
.data
);
279 gnutls_free (y
.data
);
291 print_cert (gnutls_buffer_st
* str
, gnutls_openpgp_crt_t cert
)
296 print_key_revoked (str
, cert
, -1);
300 int version
= gnutls_openpgp_crt_get_version (cert
);
302 addf (str
, "error: get_version: %s\n", gnutls_strerror (version
));
304 addf (str
, _("\tVersion: %d\n"), version
);
308 print_key_id (str
, cert
, -1);
310 print_key_fingerprint (str
, cert
);
319 err
= gnutls_openpgp_crt_get_name (cert
, i
, NULL
, &dn_size
);
320 if (err
!= GNUTLS_E_SHORT_MEMORY_BUFFER
321 && err
!= GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
322 && err
!= GNUTLS_E_OPENPGP_UID_REVOKED
)
323 addf (str
, "error: get_name: %s\n", gnutls_strerror (err
));
326 dn
= gnutls_malloc (dn_size
);
328 addf (str
, "error: malloc (%d): %s\n", (int) dn_size
,
329 gnutls_strerror (GNUTLS_E_MEMORY_ERROR
));
332 err
= gnutls_openpgp_crt_get_name (cert
, i
, dn
, &dn_size
);
333 if (err
< 0 && err
!= GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
&&
334 err
!= GNUTLS_E_OPENPGP_UID_REVOKED
)
335 addf (str
, "error: get_name: %s\n", gnutls_strerror (err
));
337 addf (str
, _("\tName[%d]: %s\n"), i
, dn
);
338 else if (err
== GNUTLS_E_OPENPGP_UID_REVOKED
)
339 addf (str
, _("\tRevoked Name[%d]: %s\n"), i
, dn
);
349 print_key_times (str
, cert
, -1);
351 print_key_info (str
, cert
, -1);
352 print_key_usage (str
, cert
, -1);
354 subkeys
= gnutls_openpgp_crt_get_subkey_count (cert
);
358 for (i
= 0; i
< subkeys
; i
++)
360 addf (str
, _("\n\tSubkey[%d]:\n"), i
);
362 print_key_revoked (str
, cert
, i
);
363 print_key_id (str
, cert
, i
);
364 print_key_times (str
, cert
, i
);
365 print_key_info (str
, cert
, i
);
366 print_key_usage (str
, cert
, i
);
372 print_oneline (gnutls_buffer_st
* str
, gnutls_openpgp_crt_t cert
)
382 err
= gnutls_openpgp_crt_get_name (cert
, i
, NULL
, &dn_size
);
383 if (err
!= GNUTLS_E_SHORT_MEMORY_BUFFER
384 && err
!= GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
385 && err
!= GNUTLS_E_OPENPGP_UID_REVOKED
)
386 addf (str
, "unknown name (%s), ", gnutls_strerror (err
));
389 dn
= gnutls_malloc (dn_size
);
391 addf (str
, "unknown name (%s), ",
392 gnutls_strerror (GNUTLS_E_MEMORY_ERROR
));
395 err
= gnutls_openpgp_crt_get_name (cert
, i
, dn
, &dn_size
);
396 if (err
< 0 && err
!= GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
&&
397 err
!= GNUTLS_E_OPENPGP_UID_REVOKED
)
398 addf (str
, "unknown name (%s), ", gnutls_strerror (err
));
400 addf (str
, _("name[%d]: %s, "), i
, dn
);
401 else if (err
== GNUTLS_E_OPENPGP_UID_REVOKED
)
402 addf (str
, _("revoked name[%d]: %s, "), i
, dn
);
414 size_t fpr_size
= sizeof (fpr
);
417 err
= gnutls_openpgp_crt_get_fingerprint (cert
, fpr
, &fpr_size
);
419 addf (str
, "error: get_fingerprint: %s\n", gnutls_strerror (err
));
422 adds (str
, _("fingerprint: "));
423 _gnutls_buffer_hexprint (str
, fpr
, fpr_size
);
431 tim
= gnutls_openpgp_crt_get_creation_time (cert
);
434 size_t max
= sizeof (s
);
437 if (gmtime_r (&tim
, &t
) == NULL
)
438 addf (str
, "error: gmtime_r (%ld), ", (unsigned long) tim
);
439 else if (strftime (s
, max
, "%Y-%m-%d %H:%M:%S UTC", &t
) == 0)
440 addf (str
, "error: strftime (%ld), ", (unsigned long) tim
);
442 addf (str
, _("created: %s, "), s
);
445 tim
= gnutls_openpgp_crt_get_expiration_time (cert
);
448 size_t max
= sizeof (s
);
452 adds (str
, _("never expires, "));
455 if (gmtime_r (&tim
, &t
) == NULL
)
456 addf (str
, "error: gmtime_r (%ld), ", (unsigned long) tim
);
457 else if (strftime (s
, max
, "%Y-%m-%d %H:%M:%S UTC", &t
) == 0)
458 addf (str
, "error: strftime (%ld), ", (unsigned long) tim
);
460 addf (str
, _("expires: %s, "), s
);
466 unsigned int bits
= 0;
467 gnutls_pk_algorithm_t algo
=
468 gnutls_openpgp_crt_get_pk_algorithm (cert
, &bits
);
469 const char *algostr
= gnutls_pk_algorithm_get_name (algo
);
472 addf (str
, _("key algorithm %s (%d bits)"), algostr
, bits
);
474 addf (str
, _("unknown key algorithm (%d)"), algo
);
479 * gnutls_openpgp_crt_print:
480 * @cert: The structure to be printed
481 * @format: Indicate the format to use
482 * @out: Newly allocated datum with (0) terminated string.
484 * This function will pretty print an OpenPGP certificate, suitable
485 * for display to a human.
487 * The format should be (0) for future compatibility.
489 * The output @out needs to be deallocate using gnutls_free().
491 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
494 gnutls_openpgp_crt_print (gnutls_openpgp_crt_t cert
,
495 gnutls_certificate_print_formats_t format
,
496 gnutls_datum_t
* out
)
498 gnutls_buffer_st str
;
501 _gnutls_buffer_init (&str
);
503 if (format
== GNUTLS_CRT_PRINT_ONELINE
)
504 print_oneline (&str
, cert
);
505 else if (format
== GNUTLS_CRT_PRINT_COMPACT
)
507 print_oneline (&str
, cert
);
509 _gnutls_buffer_append_data (&str
, "\n", 1);
510 print_key_fingerprint (&str
, cert
);
514 _gnutls_buffer_append_str (&str
,
515 _("OpenPGP Certificate Information:\n"));
516 print_cert (&str
, cert
);
519 _gnutls_buffer_append_data (&str
, "\0", 1);
521 ret
= _gnutls_buffer_to_datum( &str
, out
);
522 if (out
->size
> 0) out
->size
--;