Fix memory leak.
[gnutls.git] / lib / openpgp / output.c
bloba499a6fa51b2e542af8e396bdc17ef416e264edd
1 /*
2 * Copyright (C) 2007, 2008 Free Software Foundation
4 * Author: Simon Josefsson, Nikos Mavrogiannopoulos
6 * This file is part of GNUTLS.
8 * The GNUTLS library 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 2.1 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
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301, USA
25 /* Functions for printing X.509 Certificate structures
28 #include <gnutls_int.h>
29 #include <gnutls/openpgp.h>
30 #include <gnutls_errors.h>
32 /* I18n of error codes. */
33 #include "gettext.h"
34 #define _(String) dgettext (PACKAGE, String)
35 #define N_(String) gettext_noop (String)
37 #define addf _gnutls_string_append_printf
38 #define adds _gnutls_string_append_str
40 static void
41 hexdump (gnutls_string * str, const char *data, size_t len, const char *spc)
43 size_t j;
45 if (spc)
46 adds (str, spc);
47 for (j = 0; j < len; j++)
49 if (((j + 1) % 16) == 0)
51 addf (str, "%.2x\n", (unsigned char) data[j]);
52 if (spc && j != (len - 1))
53 adds (str, spc);
55 else if (j == (len - 1))
56 addf (str, "%.2x", (unsigned char) data[j]);
57 else
58 addf (str, "%.2x:", (unsigned char) data[j]);
60 if ((j % 16) != 0)
61 adds (str, "\n");
64 static void
65 hexprint (gnutls_string * str, const char *data, size_t len)
67 size_t j;
69 if (len == 0)
70 adds (str, "00");
71 else
73 for (j = 0; j < len; j++)
74 addf (str, "%.2x", (unsigned char) data[j]);
78 static void
79 print_key_usage (gnutls_string * str, gnutls_openpgp_crt_t cert, unsigned int idx)
81 unsigned int key_usage;
82 int err;
84 addf (str, _("\t\tKey Usage:\n"));
87 if (idx == -1)
88 err = gnutls_openpgp_crt_get_key_usage (cert, &key_usage);
89 else
90 err = gnutls_openpgp_crt_get_subkey_usage (cert, idx, &key_usage);
91 if (err < 0)
93 addf (str, _("error: get_key_usage: %s\n"), gnutls_strerror (err));
94 return;
97 if (key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE)
98 addf (str, _("\t\t\tDigital signatures.\n"));
99 if (key_usage & GNUTLS_KEY_KEY_ENCIPHERMENT)
100 addf (str, _("\t\t\tCommunications encipherment.\n"));
101 if (key_usage & GNUTLS_KEY_DATA_ENCIPHERMENT)
102 addf (str, _("\t\t\tStorage data encipherment.\n"));
103 if (key_usage & GNUTLS_KEY_KEY_AGREEMENT)
104 addf (str, _("\t\t\tAuthentication.\n"));
105 if (key_usage & GNUTLS_KEY_KEY_CERT_SIGN)
106 addf (str, _("\t\t\tCertificate signing.\n"));
109 /* idx == -1 indicates main key
110 * otherwise the subkey.
112 static void
113 print_key_id (gnutls_string * str, gnutls_openpgp_crt_t cert, int idx)
115 gnutls_openpgp_keyid_t id;
116 int err;
118 if (idx < 0)
119 err = gnutls_openpgp_crt_get_key_id (cert, id);
120 else
121 err = gnutls_openpgp_crt_get_subkey_id( cert, idx, id);
123 if (err < 0)
124 addf (str, "error: get_key_id: %s\n", gnutls_strerror (err));
125 else
127 addf (str, _("\tID (hex): "));
128 hexprint (str, id, sizeof(id));
129 addf (str, "\n");
133 /* idx == -1 indicates main key
134 * otherwise the subkey.
136 static void
137 print_key_fingerprint (gnutls_string * str, gnutls_openpgp_crt_t cert)
139 char fpr[128];
140 size_t fpr_size = sizeof (fpr);
141 int err;
143 err = gnutls_openpgp_crt_get_fingerprint (cert, fpr, &fpr_size);
144 if (err < 0)
145 addf (str, "error: get_fingerprint: %s\n", gnutls_strerror (err));
146 else
148 addf (str, _("\tFingerprint (hex): "));
149 hexprint (str, fpr, fpr_size);
150 addf (str, "\n");
154 static void
155 print_key_revoked (gnutls_string * str, gnutls_openpgp_crt_t cert, int idx)
157 int err;
159 if (idx < 0)
160 err = gnutls_openpgp_crt_get_revoked_status (cert);
161 else
162 err = gnutls_openpgp_crt_get_subkey_revoked_status( cert, idx);
164 if (err != 0)
165 addf (str, _("\tRevoked: True\n"));
166 else
167 addf (str, _("\tRevoked: False\n"));
170 static void
171 print_key_times(gnutls_string * str, gnutls_openpgp_crt_t cert, int idx)
173 time_t tim;
175 addf (str, _("\tTime stamps:\n"));
177 if (idx == -1)
178 tim = gnutls_openpgp_crt_get_creation_time (cert);
179 else
180 tim = gnutls_openpgp_crt_get_subkey_creation_time (cert, idx);
183 char s[42];
184 size_t max = sizeof (s);
185 struct tm t;
187 if (gmtime_r (&tim, &t) == NULL)
188 addf (str, "error: gmtime_r (%d)\n", t);
189 else if (strftime (s, max, "%a %b %e %H:%M:%S UTC %Y", &t) == 0)
190 addf (str, "error: strftime (%d)\n", t);
191 else
192 addf (str, _("\t\tCreation: %s\n"), s);
195 if (idx == -1)
196 tim = gnutls_openpgp_crt_get_expiration_time (cert);
197 else
198 tim = gnutls_openpgp_crt_get_subkey_expiration_time (cert, idx);
200 char s[42];
201 size_t max = sizeof (s);
202 struct tm t;
204 if (tim == 0)
206 addf (str, _("\t\tExpiration: Never\n"), s);
208 else
210 if (gmtime_r (&tim, &t) == NULL)
211 addf (str, "error: gmtime_r (%d)\n", t);
212 else if (strftime (s, max, "%a %b %e %H:%M:%S UTC %Y", &t) == 0)
213 addf (str, "error: strftime (%d)\n", t);
214 else
215 addf (str, _("\t\tExpiration: %s\n"), s);
220 static void
221 print_key_info(gnutls_string * str, gnutls_openpgp_crt_t cert, int idx)
223 int err;
224 unsigned int bits;
226 if (idx == -1)
227 err = gnutls_openpgp_crt_get_pk_algorithm (cert, &bits);
228 else
229 err = gnutls_openpgp_crt_get_subkey_pk_algorithm (cert, idx, &bits);
231 if (err < 0)
232 addf (str, "error: get_pk_algorithm: %s\n", gnutls_strerror (err));
233 else
235 const char *name = gnutls_pk_algorithm_get_name (err);
236 if (name == NULL)
237 name = _("unknown");
239 addf (str, _("\tPublic Key Algorithm: %s\n"), name);
240 switch (err)
242 case GNUTLS_PK_RSA:
244 gnutls_datum_t m, e;
246 if (idx == -1)
247 err = gnutls_openpgp_crt_get_pk_rsa_raw (cert, &m, &e);
248 else
249 err = gnutls_openpgp_crt_get_subkey_pk_rsa_raw (cert, idx, &m, &e);
251 if (err < 0)
252 addf (str, "error: get_pk_rsa_raw: %s\n",
253 gnutls_strerror (err));
254 else
256 addf (str, _("\t\tModulus (bits %d):\n"), bits);
257 hexdump (str, m.data, m.size, "\t\t\t");
258 addf (str, _("\t\tExponent:\n"));
259 hexdump (str, e.data, e.size, "\t\t\t");
261 gnutls_free (m.data);
262 gnutls_free (e.data);
266 break;
268 case GNUTLS_PK_DSA:
270 gnutls_datum_t p, q, g, y;
272 if (idx == -1)
273 err = gnutls_openpgp_crt_get_pk_dsa_raw (cert, &p, &q, &g, &y);
274 else
275 err = gnutls_openpgp_crt_get_subkey_pk_dsa_raw (cert, idx, &p, &q, &g, &y);
276 if (err < 0)
277 addf (str, "error: get_pk_dsa_raw: %s\n",
278 gnutls_strerror (err));
279 else
281 addf (str, _("\t\tPublic key (bits %d):\n"), bits);
282 hexdump (str, y.data, y.size, "\t\t\t");
283 addf (str, _("\t\tP:\n"));
284 hexdump (str, p.data, p.size, "\t\t\t");
285 addf (str, _("\t\tQ:\n"));
286 hexdump (str, q.data, q.size, "\t\t\t");
287 addf (str, _("\t\tG:\n"));
288 hexdump (str, g.data, g.size, "\t\t\t");
290 gnutls_free (p.data);
291 gnutls_free (q.data);
292 gnutls_free (g.data);
293 gnutls_free (y.data);
296 break;
298 default:
299 break;
305 static void
306 print_cert (gnutls_string * str, gnutls_openpgp_crt_t cert, unsigned int format)
308 int i, subkeys;
309 int err;
310 char dn[1024];
311 size_t dn_size;
313 print_key_revoked( str, cert, -1);
315 /* Version. */
317 int version = gnutls_openpgp_crt_get_version (cert);
318 if (version < 0)
319 addf (str, "error: get_version: %s\n", gnutls_strerror (version));
320 else
321 addf (str, _("\tVersion: %d\n"), version);
324 /* ID. */
325 print_key_id( str, cert, -1);
327 print_key_fingerprint( str, cert);
329 /* Names. */
330 i = 0;
331 do {
332 dn_size = sizeof(dn);
333 err = gnutls_openpgp_crt_get_name (cert, i++, dn, &dn_size);
335 if (err < 0 && err != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE &&
336 err != GNUTLS_E_OPENPGP_UID_REVOKED)
338 addf (str, "error: get_name: %s %d\n", gnutls_strerror (err), err);
339 break;
342 if (err >= 0)
343 addf (str, _("\tName[%d]: %s\n"), i-1, dn);
344 else if (err == GNUTLS_E_OPENPGP_UID_REVOKED) {
345 addf (str, _("\tRevoked Name[%d]: %s\n"), i-1, dn);
348 } while( err >= 0);
350 print_key_times( str, cert, -1);
352 print_key_info( str, cert, -1);
353 print_key_usage( str, cert, -1);
355 subkeys = gnutls_openpgp_crt_get_subkey_count( cert);
356 if (subkeys < 0)
357 return;
359 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 * gnutls_openpgp_crt_print - Pretty print OpenPGP certificates
373 * @cert: The structure to be printed
374 * @format: Indicate the format to use
375 * @out: Newly allocated datum with zero terminated string.
377 * This function will pretty print an OpenPGP certificate, suitable
378 * for display to a human.
380 * The format should be zero for future compatibility.
382 * The output @out needs to be deallocate using gnutls_free().
384 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
387 gnutls_openpgp_crt_print (gnutls_openpgp_crt_t cert,
388 gnutls_certificate_print_formats_t format,
389 gnutls_datum_t *out)
391 gnutls_string str;
393 _gnutls_string_init (&str, gnutls_malloc, gnutls_realloc, gnutls_free);
395 _gnutls_string_append_str (&str, _("OpenPGP Certificate Information:\n"));
397 print_cert (&str, cert, format);
399 _gnutls_string_append_data (&str, "\0", 1);
400 out->data = str.data;
401 out->size = strlen (str.data);
403 return 0;