Use the new asn1_read_node_value()
[gnutls.git] / lib / x509 / output.c
blob1797b26419aaabeb3df323226ef9196720907d81
1 /*
2 * Copyright (C) 2007-2012 Free Software Foundation, Inc.
4 * Author: Simon Josefsson
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 <common.h>
28 #include <gnutls_x509.h>
29 #include <x509_int.h>
30 #include <gnutls_num.h>
31 #include <gnutls_errors.h>
32 #include <extras/randomart.h>
34 /* I18n of error codes. */
35 #include "gettext.h"
36 #define _(String) dgettext (PACKAGE, String)
38 #define addf _gnutls_buffer_append_printf
39 #define adds _gnutls_buffer_append_str
41 #define ERROR_STR (char*) "(error)"
43 static char *
44 ip_to_string (void *_ip, int ip_size, char *string, int string_size)
46 uint8_t *ip;
48 if (ip_size != 4 && ip_size != 16)
50 gnutls_assert ();
51 return NULL;
54 if (ip_size == 4 && string_size < 16)
56 gnutls_assert ();
57 return NULL;
60 if (ip_size == 16 && string_size < 48)
62 gnutls_assert ();
63 return NULL;
66 ip = _ip;
67 switch (ip_size)
69 case 4:
70 snprintf (string, string_size, "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]);
71 break;
72 case 16:
73 snprintf (string, string_size, "%x:%x:%x:%x:%x:%x:%x:%x",
74 (ip[0] << 8) | ip[1], (ip[2] << 8) | ip[3],
75 (ip[4] << 8) | ip[5], (ip[6] << 8) | ip[7],
76 (ip[8] << 8) | ip[9], (ip[10] << 8) | ip[11],
77 (ip[12] << 8) | ip[13], (ip[14] << 8) | ip[15]);
78 break;
81 return string;
84 static void add_altname(gnutls_buffer_st * str, const char* prefix, unsigned int alt_type,
85 char* name, size_t name_size)
87 char str_ip[64];
88 char *p;
90 if ((alt_type == GNUTLS_SAN_DNSNAME
91 || alt_type == GNUTLS_SAN_RFC822NAME
92 || alt_type == GNUTLS_SAN_URI) && strlen (name) != name_size)
94 adds (str, _("warning: altname contains an embedded NUL, "
95 "replacing with '!'\n"));
96 while (strlen (name) < name_size)
97 name[strlen (name)] = '!';
100 switch (alt_type)
102 case GNUTLS_SAN_DNSNAME:
103 addf (str, "%s\t\t\tDNSname: %.*s\n", prefix, (int) name_size, name);
104 break;
106 case GNUTLS_SAN_RFC822NAME:
107 addf (str, "%s\t\t\tRFC822name: %.*s\n", prefix, (int) name_size,
108 name);
109 break;
111 case GNUTLS_SAN_URI:
112 addf (str, "%s\t\t\tURI: %.*s\n", prefix, (int) name_size, name);
113 break;
115 case GNUTLS_SAN_IPADDRESS:
116 p = ip_to_string (name, name_size, str_ip, sizeof (str_ip));
117 if (p == NULL)
118 p = ERROR_STR;
119 addf (str, "%s\t\t\tIPAddress: %s\n", prefix, p);
120 break;
122 case GNUTLS_SAN_DN:
123 addf (str, "%s\t\t\tdirectoryName: %.*s\n", prefix,
124 (int) name_size, name);
125 break;
126 default:
127 addf (str, "error: unknown altname\n");
128 break;
132 static void
133 print_proxy (gnutls_buffer_st * str, gnutls_x509_crt_t cert)
135 int pathlen;
136 char *policyLanguage;
137 char *policy;
138 size_t npolicy;
139 int err;
141 err = gnutls_x509_crt_get_proxy (cert, NULL,
142 &pathlen, &policyLanguage,
143 &policy, &npolicy);
144 if (err < 0)
146 addf (str, "error: get_proxy: %s\n", gnutls_strerror (err));
147 return;
150 if (pathlen >= 0)
151 addf (str, _("\t\t\tPath Length Constraint: %d\n"), pathlen);
152 addf (str, _("\t\t\tPolicy Language: %s"), policyLanguage);
153 if (strcmp (policyLanguage, "1.3.6.1.5.5.7.21.1") == 0)
154 adds (str, " (id-ppl-inheritALL)\n");
155 else if (strcmp (policyLanguage, "1.3.6.1.5.5.7.21.2") == 0)
156 adds (str, " (id-ppl-independent)\n");
157 else
158 adds (str, "\n");
159 if (npolicy)
161 adds (str, _("\t\t\tPolicy:\n\t\t\t\tASCII: "));
162 _gnutls_buffer_asciiprint (str, policy, npolicy);
163 adds (str, _("\n\t\t\t\tHexdump: "));
164 _gnutls_buffer_hexprint (str, policy, npolicy);
165 adds (str, "\n");
169 static void
170 print_aia (gnutls_buffer_st * str, gnutls_x509_crt_t cert)
172 int err;
173 int seq = 0;
174 gnutls_datum_t data;
176 for (;;)
178 err = gnutls_x509_crt_get_authority_info_access
179 (cert, seq, GNUTLS_IA_ACCESSMETHOD_OID, &data, NULL);
180 if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
181 return;
182 if (err < 0)
184 addf (str, "error: get_aia: %s\n", gnutls_strerror (err));
185 return;
188 addf (str, _("\t\t\tAccess Method: %.*s"), data.size, data.data);
189 if (data.size == sizeof (GNUTLS_OID_AD_OCSP) &&
190 memcmp (data.data, GNUTLS_OID_AD_OCSP, data.size) == 0)
191 adds (str, " (id-ad-ocsp)\n");
192 else if (data.size == sizeof (GNUTLS_OID_AD_CAISSUERS) &&
193 memcmp (data.data, GNUTLS_OID_AD_CAISSUERS, data.size) == 0)
194 adds (str, " (id-ad-caIssuers)\n");
195 else
196 adds (str, " (UNKNOWN)\n");
198 err = gnutls_x509_crt_get_authority_info_access
199 (cert, seq, GNUTLS_IA_ACCESSLOCATION_GENERALNAME_TYPE, &data, NULL);
200 if (err < 0)
202 addf (str, "error: get_aia type: %s\n", gnutls_strerror (err));
203 return;
206 if (data.size == sizeof ("uniformResourceIdentifier") &&
207 memcmp (data.data, "uniformResourceIdentifier", data.size) == 0)
209 adds (str, "\t\t\tAccess Location URI: ");
210 err = gnutls_x509_crt_get_authority_info_access
211 (cert, seq, GNUTLS_IA_URI, &data, NULL);
212 if (err < 0)
214 addf (str, "error: get_aia uri: %s\n", gnutls_strerror (err));
215 return;
217 addf (str, "%.*s\n", data.size, data.data);
219 else
220 adds (str, "\t\t\tUnsupported accessLocation type\n");
222 seq++;
226 static void
227 print_ski (gnutls_buffer_st * str, gnutls_x509_crt_t cert)
229 char *buffer = NULL;
230 size_t size = 0;
231 int err;
233 err = gnutls_x509_crt_get_subject_key_id (cert, buffer, &size, NULL);
234 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
236 addf (str, "error: get_subject_key_id: %s\n", gnutls_strerror (err));
237 return;
240 buffer = gnutls_malloc (size);
241 if (!buffer)
243 addf (str, "error: malloc: %s\n",
244 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
245 return;
248 err = gnutls_x509_crt_get_subject_key_id (cert, buffer, &size, NULL);
249 if (err < 0)
251 gnutls_free (buffer);
252 addf (str, "error: get_subject_key_id2: %s\n", gnutls_strerror (err));
253 return;
256 adds (str, "\t\t\t");
257 _gnutls_buffer_hexprint (str, buffer, size);
258 adds (str, "\n");
260 gnutls_free (buffer);
263 #define TYPE_CRL 1
264 #define TYPE_CRT 2
265 #define TYPE_CRQ 3
267 #define TYPE_CRT_SAN TYPE_CRT
268 #define TYPE_CRQ_SAN TYPE_CRQ
269 #define TYPE_CRT_IAN 4
271 typedef union
273 gnutls_x509_crt_t crt;
274 gnutls_x509_crq_t crq;
275 gnutls_x509_crl_t crl;
276 } cert_type_t;
278 static void
279 print_aki_gn_serial (gnutls_buffer_st * str, int type, cert_type_t cert)
281 char *buffer = NULL;
282 char serial[128];
283 size_t size = 0, serial_size = sizeof(serial);
284 unsigned int alt_type;
285 int err;
287 if (type == TYPE_CRT)
288 err =
289 gnutls_x509_crt_get_authority_key_gn_serial(cert.crt, 0, NULL, &size,
290 &alt_type, serial, &serial_size, NULL);
291 else if (type == TYPE_CRL)
292 err =
293 gnutls_x509_crl_get_authority_key_gn_serial(cert.crl, 0, NULL, &size,
294 &alt_type, serial, &serial_size, NULL);
295 else
297 gnutls_assert ();
298 return;
301 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
303 addf (str, "error: get_authority_key_gn_serial: %s\n", gnutls_strerror (err));
304 return;
307 buffer = gnutls_malloc (size);
308 if (!buffer)
310 addf (str, "error: malloc: %s\n",
311 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
312 return;
315 if (type == TYPE_CRT)
316 err =
317 gnutls_x509_crt_get_authority_key_gn_serial(cert.crt, 0, buffer, &size,
318 &alt_type, serial, &serial_size, NULL);
319 else
320 err =
321 gnutls_x509_crl_get_authority_key_gn_serial(cert.crl, 0, buffer, &size,
322 &alt_type, serial, &serial_size, NULL);
324 if (err < 0)
326 gnutls_free (buffer);
327 addf (str, "error: get_authority_key_gn_serial2: %s\n", gnutls_strerror (err));
328 return;
331 add_altname(str, "", alt_type, buffer, size);
332 adds (str, "\t\t\tserial: ");
333 _gnutls_buffer_hexprint (str, serial, serial_size);
334 adds (str, "\n");
336 gnutls_free (buffer);
339 static void
340 print_aki (gnutls_buffer_st * str, int type, cert_type_t cert)
342 char *buffer = NULL;
343 size_t size = 0;
344 int err;
346 if (type == TYPE_CRT)
347 err =
348 gnutls_x509_crt_get_authority_key_id (cert.crt, buffer, &size, NULL);
349 else if (type == TYPE_CRL)
350 err =
351 gnutls_x509_crl_get_authority_key_id (cert.crl, buffer, &size, NULL);
352 else
354 gnutls_assert ();
355 return;
358 if (err == GNUTLS_E_X509_UNSUPPORTED_EXTENSION)
360 /* Check if an alternative name is there */
361 print_aki_gn_serial(str, type, cert);
362 return;
365 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
367 addf (str, "error: get_authority_key_id: %s\n", gnutls_strerror (err));
368 return;
371 buffer = gnutls_malloc (size);
372 if (!buffer)
374 addf (str, "error: malloc: %s\n",
375 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
376 return;
379 if (type == TYPE_CRT)
380 err =
381 gnutls_x509_crt_get_authority_key_id (cert.crt, buffer, &size, NULL);
382 else
383 err =
384 gnutls_x509_crl_get_authority_key_id (cert.crl, buffer, &size, NULL);
386 if (err < 0)
388 gnutls_free (buffer);
389 addf (str, "error: get_authority_key_id2: %s\n", gnutls_strerror (err));
390 return;
393 adds (str, "\t\t\t");
394 _gnutls_buffer_hexprint (str, buffer, size);
395 adds (str, "\n");
397 gnutls_free (buffer);
400 static void
401 print_key_usage (gnutls_buffer_st * str, const char *prefix, int type,
402 cert_type_t cert)
404 unsigned int key_usage;
405 int err;
407 if (type == TYPE_CRT)
408 err = gnutls_x509_crt_get_key_usage (cert.crt, &key_usage, NULL);
409 else if (type == TYPE_CRQ)
410 err = gnutls_x509_crq_get_key_usage (cert.crq, &key_usage, NULL);
411 else
412 return;
414 if (err < 0)
416 addf (str, "error: get_key_usage: %s\n", gnutls_strerror (err));
417 return;
420 if (key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE)
421 addf (str, _("%s\t\t\tDigital signature.\n"), prefix);
422 if (key_usage & GNUTLS_KEY_NON_REPUDIATION)
423 addf (str, _("%s\t\t\tNon repudiation.\n"), prefix);
424 if (key_usage & GNUTLS_KEY_KEY_ENCIPHERMENT)
425 addf (str, _("%s\t\t\tKey encipherment.\n"), prefix);
426 if (key_usage & GNUTLS_KEY_DATA_ENCIPHERMENT)
427 addf (str, _("%s\t\t\tData encipherment.\n"), prefix);
428 if (key_usage & GNUTLS_KEY_KEY_AGREEMENT)
429 addf (str, _("%s\t\t\tKey agreement.\n"), prefix);
430 if (key_usage & GNUTLS_KEY_KEY_CERT_SIGN)
431 addf (str, _("%s\t\t\tCertificate signing.\n"), prefix);
432 if (key_usage & GNUTLS_KEY_CRL_SIGN)
433 addf (str, _("%s\t\t\tCRL signing.\n"), prefix);
434 if (key_usage & GNUTLS_KEY_ENCIPHER_ONLY)
435 addf (str, _("%s\t\t\tKey encipher only.\n"), prefix);
436 if (key_usage & GNUTLS_KEY_DECIPHER_ONLY)
437 addf (str, _("%s\t\t\tKey decipher only.\n"), prefix);
440 static void
441 print_private_key_usage_period (gnutls_buffer_st * str, const char *prefix, int type,
442 cert_type_t cert)
444 time_t activation, expiration;
445 int err;
446 char s[42];
447 struct tm t;
448 size_t max;
450 if (type == TYPE_CRT)
451 err = gnutls_x509_crt_get_private_key_usage_period (cert.crt, &activation, &expiration, NULL);
452 else if (type == TYPE_CRQ)
453 err = gnutls_x509_crq_get_private_key_usage_period (cert.crq, &activation, &expiration, NULL);
454 else
455 return;
457 if (err < 0)
459 addf (str, "error: get_private_key_usage_period: %s\n", gnutls_strerror (err));
460 return;
463 max = sizeof (s);
465 if (gmtime_r (&activation, &t) == NULL)
466 addf (str, "error: gmtime_r (%ld)\n", (unsigned long) activation);
467 else if (strftime (s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0)
468 addf (str, "error: strftime (%ld)\n", (unsigned long) activation);
469 else
470 addf (str, _("\t\t\tNot Before: %s\n"), s);
472 if (gmtime_r (&expiration, &t) == NULL)
473 addf (str, "error: gmtime_r (%ld)\n", (unsigned long) expiration);
474 else if (strftime (s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0)
475 addf (str, "error: strftime (%ld)\n", (unsigned long) expiration);
476 else
477 addf (str, _("\t\t\tNot After: %s\n"), s);
481 static void
482 print_crldist (gnutls_buffer_st * str, gnutls_x509_crt_t cert)
484 char *buffer = NULL;
485 size_t size;
486 char str_ip[64];
487 char *p;
488 int err;
489 int indx;
491 for (indx = 0;; indx++)
493 size = 0;
494 err = gnutls_x509_crt_get_crl_dist_points (cert, indx, buffer, &size,
495 NULL, NULL);
496 if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
497 return;
498 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
500 addf (str, "error: get_crl_dist_points: %s\n",
501 gnutls_strerror (err));
502 return;
505 buffer = gnutls_malloc (size);
506 if (!buffer)
508 addf (str, "error: malloc: %s\n",
509 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
510 return;
513 err = gnutls_x509_crt_get_crl_dist_points (cert, indx, buffer, &size,
514 NULL, NULL);
515 if (err < 0)
517 gnutls_free (buffer);
518 addf (str, "error: get_crl_dist_points2: %s\n",
519 gnutls_strerror (err));
520 return;
523 if ((err == GNUTLS_SAN_DNSNAME
524 || err == GNUTLS_SAN_RFC822NAME
525 || err == GNUTLS_SAN_URI) && strlen (buffer) != size)
527 adds (str, _("warning: distributionPoint contains an embedded NUL, "
528 "replacing with '!'\n"));
529 while (strlen (buffer) < size)
530 buffer[strlen (buffer)] = '!';
533 switch (err)
535 case GNUTLS_SAN_DNSNAME:
536 addf (str, "\t\t\tDNSname: %.*s\n", (int) size, buffer);
537 break;
539 case GNUTLS_SAN_RFC822NAME:
540 addf (str, "\t\t\tRFC822name: %.*s\n", (int) size, buffer);
541 break;
543 case GNUTLS_SAN_URI:
544 addf (str, "\t\t\tURI: %.*s\n", (int) size, buffer);
545 break;
547 case GNUTLS_SAN_IPADDRESS:
548 p = ip_to_string (buffer, size, str_ip, sizeof (str_ip));
549 if (p == NULL)
550 p = ERROR_STR;
551 addf (str, "\t\t\tIPAddress: %s\n", p);
552 break;
554 case GNUTLS_SAN_DN:
555 addf (str, "\t\t\tdirectoryName: %.*s\n", (int) size, buffer);
556 break;
558 default:
559 addf (str, "error: unknown SAN\n");
560 break;
562 gnutls_free (buffer);
566 static void
567 print_key_purpose (gnutls_buffer_st * str, const char *prefix, int type,
568 cert_type_t cert)
570 int indx;
571 char *buffer = NULL;
572 size_t size;
573 int err;
575 for (indx = 0;; indx++)
577 size = 0;
578 if (type == TYPE_CRT)
579 err = gnutls_x509_crt_get_key_purpose_oid (cert.crt, indx, buffer,
580 &size, NULL);
581 else if (type == TYPE_CRQ)
582 err = gnutls_x509_crq_get_key_purpose_oid (cert.crq, indx, buffer,
583 &size, NULL);
584 else
585 return;
587 if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
588 return;
589 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
591 addf (str, "error: get_key_purpose_oid: %s\n",
592 gnutls_strerror (err));
593 return;
596 buffer = gnutls_malloc (size);
597 if (!buffer)
599 addf (str, "error: malloc: %s\n",
600 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
601 return;
604 if (type == TYPE_CRT)
605 err = gnutls_x509_crt_get_key_purpose_oid (cert.crt, indx, buffer,
606 &size, NULL);
607 else
608 err = gnutls_x509_crq_get_key_purpose_oid (cert.crq, indx, buffer,
609 &size, NULL);
611 if (err < 0)
613 gnutls_free (buffer);
614 addf (str, "error: get_key_purpose_oid2: %s\n",
615 gnutls_strerror (err));
616 return;
619 if (strcmp (buffer, GNUTLS_KP_TLS_WWW_SERVER) == 0)
620 addf (str, _("%s\t\t\tTLS WWW Server.\n"), prefix);
621 else if (strcmp (buffer, GNUTLS_KP_TLS_WWW_CLIENT) == 0)
622 addf (str, _("%s\t\t\tTLS WWW Client.\n"), prefix);
623 else if (strcmp (buffer, GNUTLS_KP_CODE_SIGNING) == 0)
624 addf (str, _("%s\t\t\tCode signing.\n"), prefix);
625 else if (strcmp (buffer, GNUTLS_KP_EMAIL_PROTECTION) == 0)
626 addf (str, _("%s\t\t\tEmail protection.\n"), prefix);
627 else if (strcmp (buffer, GNUTLS_KP_TIME_STAMPING) == 0)
628 addf (str, _("%s\t\t\tTime stamping.\n"), prefix);
629 else if (strcmp (buffer, GNUTLS_KP_OCSP_SIGNING) == 0)
630 addf (str, _("%s\t\t\tOCSP signing.\n"), prefix);
631 else if (strcmp (buffer, GNUTLS_KP_IPSEC_IKE) == 0)
632 addf (str, _("%s\t\t\tIpsec IKE.\n"), prefix);
633 else if (strcmp (buffer, GNUTLS_KP_ANY) == 0)
634 addf (str, _("%s\t\t\tAny purpose.\n"), prefix);
635 else
636 addf (str, "%s\t\t\t%s\n", prefix, buffer);
638 gnutls_free (buffer);
642 static void
643 print_basic (gnutls_buffer_st * str, const char *prefix, int type,
644 cert_type_t cert)
646 int pathlen;
647 int err;
649 if (type == TYPE_CRT)
650 err =
651 gnutls_x509_crt_get_basic_constraints (cert.crt, NULL, NULL, &pathlen);
652 else if (type == TYPE_CRQ)
653 err =
654 gnutls_x509_crq_get_basic_constraints (cert.crq, NULL, NULL, &pathlen);
655 else
656 return;
658 if (err < 0)
660 addf (str, "error: get_basic_constraints: %s\n", gnutls_strerror (err));
661 return;
664 if (err == 0)
665 addf (str, _("%s\t\t\tCertificate Authority (CA): FALSE\n"), prefix);
666 else
667 addf (str, _("%s\t\t\tCertificate Authority (CA): TRUE\n"), prefix);
669 if (pathlen >= 0)
670 addf (str, _("%s\t\t\tPath Length Constraint: %d\n"), prefix, pathlen);
674 static void
675 print_altname (gnutls_buffer_st * str, const char *prefix, unsigned int altname_type,
676 cert_type_t cert)
678 unsigned int altname_idx;
680 for (altname_idx = 0;; altname_idx++)
682 char *buffer = NULL;
683 size_t size = 0;
684 int err;
686 if (altname_type == TYPE_CRT_SAN)
687 err =
688 gnutls_x509_crt_get_subject_alt_name (cert.crt, altname_idx, buffer,
689 &size, NULL);
690 else if (altname_type == TYPE_CRQ_SAN)
691 err =
692 gnutls_x509_crq_get_subject_alt_name (cert.crq, altname_idx, buffer,
693 &size, NULL, NULL);
694 else if (altname_type == TYPE_CRT_IAN)
695 err =
696 gnutls_x509_crt_get_issuer_alt_name (cert.crt, altname_idx, buffer,
697 &size, NULL);
698 else
699 return;
701 if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
702 break;
703 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
705 addf (str, "error: get_subject/issuer_alt_name: %s\n",
706 gnutls_strerror (err));
707 return;
710 buffer = gnutls_malloc (size);
711 if (!buffer)
713 addf (str, "error: malloc: %s\n",
714 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
715 return;
718 if (altname_type == TYPE_CRT_SAN)
719 err =
720 gnutls_x509_crt_get_subject_alt_name (cert.crt, altname_idx, buffer,
721 &size, NULL);
722 else if (altname_type == TYPE_CRQ_SAN)
723 err =
724 gnutls_x509_crq_get_subject_alt_name (cert.crq, altname_idx, buffer,
725 &size, NULL, NULL);
726 else if (altname_type == TYPE_CRT_IAN)
727 err = gnutls_x509_crt_get_issuer_alt_name (cert.crt, altname_idx,
728 buffer, &size, NULL);
730 if (err < 0)
732 gnutls_free (buffer);
733 addf (str, "error: get_subject/issuer_alt_name2: %s\n",
734 gnutls_strerror (err));
735 return;
739 if (err == GNUTLS_SAN_OTHERNAME)
741 char *oid = NULL;
742 size_t oidsize;
744 oidsize = 0;
745 if (altname_type == TYPE_CRT_SAN)
746 err = gnutls_x509_crt_get_subject_alt_othername_oid
747 (cert.crt, altname_idx, oid, &oidsize);
748 else if (altname_type == TYPE_CRQ_SAN)
749 err = gnutls_x509_crq_get_subject_alt_othername_oid
750 (cert.crq, altname_idx, oid, &oidsize);
751 else if (altname_type == TYPE_CRT_IAN)
752 err = gnutls_x509_crt_get_issuer_alt_othername_oid
753 (cert.crt, altname_idx, oid, &oidsize);
755 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
757 gnutls_free (buffer);
758 addf (str,
759 "error: get_subject/issuer_alt_othername_oid: %s\n",
760 gnutls_strerror (err));
761 return;
764 oid = gnutls_malloc (oidsize);
765 if (!oid)
767 gnutls_free (buffer);
768 addf (str, "error: malloc: %s\n",
769 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
770 return;
773 if (altname_type == TYPE_CRT_SAN)
774 err = gnutls_x509_crt_get_subject_alt_othername_oid
775 (cert.crt, altname_idx, oid, &oidsize);
776 else if (altname_type == TYPE_CRQ_SAN)
777 err = gnutls_x509_crq_get_subject_alt_othername_oid
778 (cert.crq, altname_idx, oid, &oidsize);
779 else if (altname_type == TYPE_CRT_IAN)
780 err = gnutls_x509_crt_get_issuer_alt_othername_oid
781 (cert.crt, altname_idx, oid, &oidsize);
783 if (err < 0)
785 gnutls_free (buffer);
786 gnutls_free (oid);
787 addf (str, "error: get_subject_alt_othername_oid2: %s\n",
788 gnutls_strerror (err));
789 return;
792 if (err == GNUTLS_SAN_OTHERNAME_XMPP)
794 if (strlen (buffer) != size)
796 adds (str, _("warning: altname contains an embedded NUL, "
797 "replacing with '!'\n"));
798 while (strlen (buffer) < size)
799 buffer[strlen (buffer)] = '!';
802 addf (str, _("%s\t\t\tXMPP Address: %.*s\n"), prefix,
803 (int) size, buffer);
805 else
807 addf (str, _("%s\t\t\totherName OID: %.*s\n"), prefix,
808 (int) oidsize, oid);
809 addf (str, _("%s\t\t\totherName DER: "), prefix);
810 _gnutls_buffer_hexprint (str, buffer, size);
811 addf (str, _("\n%s\t\t\totherName ASCII: "), prefix);
812 _gnutls_buffer_asciiprint (str, buffer, size);
813 addf (str, "\n");
815 gnutls_free (oid);
817 else
818 add_altname(str, prefix, err, buffer, size);
820 gnutls_free (buffer);
824 static void
825 guiddump (gnutls_buffer_st * str, const char *data, size_t len,
826 const char *spc)
828 size_t j;
830 if (spc)
831 adds (str, spc);
832 addf (str, "{");
833 addf (str, "%.2X", (unsigned char) data[3]);
834 addf (str, "%.2X", (unsigned char) data[2]);
835 addf (str, "%.2X", (unsigned char) data[1]);
836 addf (str, "%.2X", (unsigned char) data[0]);
837 addf (str, "-");
838 addf (str, "%.2X", (unsigned char) data[5]);
839 addf (str, "%.2X", (unsigned char) data[4]);
840 addf (str, "-");
841 addf (str, "%.2X", (unsigned char) data[7]);
842 addf (str, "%.2X", (unsigned char) data[6]);
843 addf (str, "-");
844 addf (str, "%.2X", (unsigned char) data[8]);
845 addf (str, "%.2X", (unsigned char) data[9]);
846 addf (str, "-");
847 for (j = 10; j < 16; j++)
849 addf (str, "%.2X", (unsigned char) data[j]);
851 addf (str, "}\n");
854 static void
855 print_unique_ids (gnutls_buffer_st * str, const gnutls_x509_crt_t cert)
857 int result;
858 char buf[256]; /* if its longer, we won't bother to print it */
859 size_t buf_size = 256;
861 result = gnutls_x509_crt_get_issuer_unique_id (cert, buf, &buf_size);
862 if (result >= 0)
864 addf (str, ("\t\tIssuer Unique ID:\n"));
865 _gnutls_buffer_hexdump (str, buf, buf_size, "\t\t\t");
866 if (buf_size == 16)
867 { /* this could be a GUID */
868 guiddump (str, buf, buf_size, "\t\t\t");
872 buf_size = 256;
873 result = gnutls_x509_crt_get_subject_unique_id (cert, buf, &buf_size);
874 if (result >= 0)
876 addf (str, ("\t\tSubject Unique ID:\n"));
877 _gnutls_buffer_hexdump (str, buf, buf_size, "\t\t\t");
878 if (buf_size == 16)
879 { /* this could be a GUID */
880 guiddump (str, buf, buf_size, "\t\t\t");
885 static void
886 print_extensions (gnutls_buffer_st * str, const char *prefix, int type,
887 cert_type_t cert)
889 int i, err;
890 int san_idx = 0;
891 int ian_idx = 0;
892 int proxy_idx = 0;
893 int basic_idx = 0;
894 int keyusage_idx = 0;
895 int keypurpose_idx = 0;
896 int ski_idx = 0;
897 int aki_idx = 0;
898 int crldist_idx = 0, pkey_usage_period_idx = 0;
900 for (i = 0;; i++)
902 char oid[MAX_OID_SIZE] = "";
903 size_t sizeof_oid = sizeof (oid);
904 unsigned int critical;
906 if (type == TYPE_CRT)
907 err = gnutls_x509_crt_get_extension_info (cert.crt, i,
908 oid, &sizeof_oid,
909 &critical);
911 else if (type == TYPE_CRQ)
912 err = gnutls_x509_crq_get_extension_info (cert.crq, i,
913 oid, &sizeof_oid,
914 &critical);
915 else
917 gnutls_assert ();
918 return;
921 if (err < 0)
923 if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
924 break;
925 addf (str, "error: get_extension_info: %s\n",
926 gnutls_strerror (err));
927 continue;
930 if (i == 0)
931 addf (str, _("%s\tExtensions:\n"), prefix);
933 if (strcmp (oid, "2.5.29.19") == 0)
935 if (basic_idx)
937 addf (str, "error: more than one basic constraint\n");
938 continue;
941 addf (str, _("%s\t\tBasic Constraints (%s):\n"), prefix,
942 critical ? _("critical") : _("not critical"));
944 print_basic (str, prefix, type, cert);
946 basic_idx++;
948 else if (strcmp (oid, "2.5.29.14") == 0)
950 if (ski_idx)
952 addf (str, "error: more than one SKI extension\n");
953 continue;
956 addf (str, _("%s\t\tSubject Key Identifier (%s):\n"), prefix,
957 critical ? _("critical") : _("not critical"));
959 if (type == TYPE_CRT)
960 print_ski (str, cert.crt);
962 ski_idx++;
964 else if (strcmp (oid, "2.5.29.35") == 0)
967 if (aki_idx)
969 addf (str, "error: more than one AKI extension\n");
970 continue;
973 addf (str, _("%s\t\tAuthority Key Identifier (%s):\n"), prefix,
974 critical ? _("critical") : _("not critical"));
976 if (type == TYPE_CRT)
977 print_aki (str, TYPE_CRT, cert);
979 aki_idx++;
981 else if (strcmp (oid, "2.5.29.15") == 0)
983 if (keyusage_idx)
985 addf (str, "error: more than one key usage extension\n");
986 continue;
989 addf (str, _("%s\t\tKey Usage (%s):\n"), prefix,
990 critical ? _("critical") : _("not critical"));
992 print_key_usage (str, prefix, type, cert);
994 keyusage_idx++;
996 else if (strcmp (oid, "2.5.29.16") == 0)
998 if (pkey_usage_period_idx)
1000 addf (str, "error: more than one private key usage period extension\n");
1001 continue;
1004 addf (str, _("%s\t\tPrivate Key Usage Period (%s):\n"), prefix,
1005 critical ? _("critical") : _("not critical"));
1007 print_private_key_usage_period (str, prefix, type, cert);
1009 pkey_usage_period_idx++;
1011 else if (strcmp (oid, "2.5.29.37") == 0)
1013 if (keypurpose_idx)
1015 addf (str, "error: more than one key purpose extension\n");
1016 continue;
1019 addf (str, _("%s\t\tKey Purpose (%s):\n"), prefix,
1020 critical ? _("critical") : _("not critical"));
1022 print_key_purpose (str, prefix, type, cert);
1023 keypurpose_idx++;
1025 else if (strcmp (oid, "2.5.29.17") == 0)
1027 if (san_idx)
1029 addf (str, "error: more than one SKI extension\n");
1030 continue;
1033 addf (str, _("%s\t\tSubject Alternative Name (%s):\n"), prefix,
1034 critical ? _("critical") : _("not critical"));
1036 print_altname (str, prefix, type, cert);
1038 san_idx++;
1040 else if (strcmp (oid, "2.5.29.18") == 0)
1042 if (ian_idx)
1044 addf (str, "error: more than one Issuer AltName extension\n");
1045 continue;
1048 addf (str, _("%s\t\tIssuer Alternative Name (%s):\n"), prefix,
1049 critical ? _("critical") : _("not critical"));
1051 print_altname (str, prefix, TYPE_CRT_IAN, cert);
1053 ian_idx++;
1055 else if (strcmp (oid, "2.5.29.31") == 0)
1057 if (crldist_idx)
1059 addf (str, "error: more than one CRL distribution point\n");
1060 continue;
1063 addf (str, _("%s\t\tCRL Distribution points (%s):\n"), prefix,
1064 critical ? _("critical") : _("not critical"));
1066 if (type == TYPE_CRT)
1067 print_crldist (str, cert.crt);
1068 crldist_idx++;
1070 else if (strcmp (oid, "1.3.6.1.5.5.7.1.14") == 0)
1072 if (proxy_idx)
1074 addf (str, "error: more than one proxy extension\n");
1075 continue;
1078 addf (str, _("%s\t\tProxy Certificate Information (%s):\n"), prefix,
1079 critical ? _("critical") : _("not critical"));
1081 if (type == TYPE_CRT)
1082 print_proxy (str, cert.crt);
1084 proxy_idx++;
1086 else if (strcmp (oid, "1.3.6.1.5.5.7.1.1") == 0)
1088 addf (str, _("%s\t\tAuthority Information "
1089 "Access (%s):\n"), prefix,
1090 critical ? _("critical") : _("not critical"));
1092 if (type == TYPE_CRT)
1093 print_aia (str, cert.crt);
1095 else
1097 char *buffer;
1098 size_t extlen = 0;
1100 addf (str, _("%s\t\tUnknown extension %s (%s):\n"), prefix, oid,
1101 critical ? _("critical") : _("not critical"));
1103 if (type == TYPE_CRT)
1104 err =
1105 gnutls_x509_crt_get_extension_data (cert.crt, i, NULL, &extlen);
1106 else if (type == TYPE_CRQ)
1107 err =
1108 gnutls_x509_crq_get_extension_data (cert.crq, i, NULL, &extlen);
1109 else
1111 gnutls_assert ();
1112 return;
1115 if (err < 0)
1117 addf (str, "error: get_extension_data: %s\n",
1118 gnutls_strerror (err));
1119 continue;
1122 buffer = gnutls_malloc (extlen);
1123 if (!buffer)
1125 addf (str, "error: malloc: %s\n",
1126 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
1127 continue;
1130 if (type == TYPE_CRT)
1131 err =
1132 gnutls_x509_crt_get_extension_data (cert.crt, i, buffer,
1133 &extlen);
1134 else if (type == TYPE_CRQ)
1135 err =
1136 gnutls_x509_crq_get_extension_data (cert.crq, i, buffer,
1137 &extlen);
1139 if (err < 0)
1141 gnutls_free (buffer);
1142 addf (str, "error: get_extension_data2: %s\n",
1143 gnutls_strerror (err));
1144 continue;
1147 addf (str, _("%s\t\t\tASCII: "), prefix);
1148 _gnutls_buffer_asciiprint (str, buffer, extlen);
1149 addf (str, "\n");
1151 addf (str, _("%s\t\t\tHexdump: "), prefix);
1152 _gnutls_buffer_hexprint (str, buffer, extlen);
1153 adds (str, "\n");
1155 gnutls_free (buffer);
1160 static void
1161 print_cert (gnutls_buffer_st * str, gnutls_x509_crt_t cert, int notsigned)
1163 /* Version. */
1165 int version = gnutls_x509_crt_get_version (cert);
1166 if (version < 0)
1167 addf (str, "error: get_version: %s\n", gnutls_strerror (version));
1168 else
1169 addf (str, _("\tVersion: %d\n"), version);
1172 /* Serial. */
1174 char serial[128];
1175 size_t serial_size = sizeof (serial);
1176 int err;
1178 err = gnutls_x509_crt_get_serial (cert, serial, &serial_size);
1179 if (err < 0)
1180 addf (str, "error: get_serial: %s\n", gnutls_strerror (err));
1181 else
1183 adds (str, _("\tSerial Number (hex): "));
1184 _gnutls_buffer_hexprint (str, serial, serial_size);
1185 adds (str, "\n");
1189 /* Issuer. */
1190 if (!notsigned)
1192 char *dn;
1193 size_t dn_size = 0;
1194 int err;
1196 err = gnutls_x509_crt_get_issuer_dn (cert, NULL, &dn_size);
1197 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
1198 addf (str, "error: get_issuer_dn: %s\n", gnutls_strerror (err));
1199 else
1201 dn = gnutls_malloc (dn_size);
1202 if (!dn)
1203 addf (str, "error: malloc (%d): %s\n", (int) dn_size,
1204 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
1205 else
1207 err = gnutls_x509_crt_get_issuer_dn (cert, dn, &dn_size);
1208 if (err < 0)
1209 addf (str, "error: get_issuer_dn: %s\n",
1210 gnutls_strerror (err));
1211 else
1212 addf (str, _("\tIssuer: %s\n"), dn);
1213 gnutls_free (dn);
1218 /* Validity. */
1220 time_t tim;
1222 adds (str, _("\tValidity:\n"));
1224 tim = gnutls_x509_crt_get_activation_time (cert);
1226 char s[42];
1227 size_t max = sizeof (s);
1228 struct tm t;
1230 if (gmtime_r (&tim, &t) == NULL)
1231 addf (str, "error: gmtime_r (%ld)\n", (unsigned long) tim);
1232 else if (strftime (s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0)
1233 addf (str, "error: strftime (%ld)\n", (unsigned long) tim);
1234 else
1235 addf (str, _("\t\tNot Before: %s\n"), s);
1238 tim = gnutls_x509_crt_get_expiration_time (cert);
1240 char s[42];
1241 size_t max = sizeof (s);
1242 struct tm t;
1244 if (gmtime_r (&tim, &t) == NULL)
1245 addf (str, "error: gmtime_r (%ld)\n", (unsigned long) tim);
1246 else if (strftime (s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0)
1247 addf (str, "error: strftime (%ld)\n", (unsigned long) tim);
1248 else
1249 addf (str, _("\t\tNot After: %s\n"), s);
1253 /* Subject. */
1255 char *dn;
1256 size_t dn_size = 0;
1257 int err;
1259 err = gnutls_x509_crt_get_dn (cert, NULL, &dn_size);
1260 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
1261 addf (str, "error: get_dn: %s\n", gnutls_strerror (err));
1262 else
1264 dn = gnutls_malloc (dn_size);
1265 if (!dn)
1266 addf (str, "error: malloc (%d): %s\n", (int) dn_size,
1267 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
1268 else
1270 err = gnutls_x509_crt_get_dn (cert, dn, &dn_size);
1271 if (err < 0)
1272 addf (str, "error: get_dn: %s\n", gnutls_strerror (err));
1273 else
1274 addf (str, _("\tSubject: %s\n"), dn);
1275 gnutls_free (dn);
1280 /* SubjectPublicKeyInfo. */
1282 int err, pk;
1283 unsigned int bits;
1285 err = gnutls_x509_crt_get_pk_algorithm (cert, &bits);
1286 if (err < 0)
1287 addf (str, "error: get_pk_algorithm: %s\n", gnutls_strerror (err));
1288 else
1290 gnutls_pubkey_t pubkey;
1291 const char *name = gnutls_pk_algorithm_get_name (err);
1292 if (name == NULL)
1293 name = _("unknown");
1295 pk = err;
1297 addf (str, _("\tSubject Public Key Algorithm: %s\n"), name);
1298 addf (str, _("\tCertificate Security Level: %s (%d bits)\n"),
1299 gnutls_sec_param_get_name (gnutls_pk_bits_to_sec_param
1300 (err, bits)), bits);
1301 err = gnutls_pubkey_init(&pubkey);
1302 if (err < 0)
1304 addf (str, "error: gnutls_pubkey_init: %s\n", gnutls_strerror (err));
1305 return;
1308 err = gnutls_pubkey_import_x509(pubkey, cert, 0);
1309 if (err < 0)
1311 addf (str, "error: gnutls_pubkey_import_x509: %s\n", gnutls_strerror (err));
1312 return;
1315 switch (pk)
1317 case GNUTLS_PK_RSA:
1319 gnutls_datum_t m, e;
1321 err = gnutls_pubkey_get_pk_rsa_raw (pubkey, &m, &e);
1322 if (err < 0)
1323 addf (str, "error: get_pk_rsa_raw: %s\n",
1324 gnutls_strerror (err));
1325 else
1327 addf (str, _("\t\tModulus (bits %d):\n"), bits);
1328 _gnutls_buffer_hexdump (str, m.data, m.size, "\t\t\t");
1329 addf (str, _("\t\tExponent (bits %d):\n"), e.size * 8);
1330 _gnutls_buffer_hexdump (str, e.data, e.size, "\t\t\t");
1332 gnutls_free (m.data);
1333 gnutls_free (e.data);
1337 break;
1339 case GNUTLS_PK_EC:
1341 gnutls_datum_t x, y;
1342 gnutls_ecc_curve_t curve;
1344 err = gnutls_pubkey_get_pk_ecc_raw (pubkey, &curve, &x, &y);
1345 if (err < 0)
1346 addf (str, "error: get_pk_ecc_raw: %s\n",
1347 gnutls_strerror (err));
1348 else
1350 addf (str, _("\t\tCurve:\t%s\n"), gnutls_ecc_curve_get_name(curve));
1351 addf (str, _("\t\tX:\n"));
1352 _gnutls_buffer_hexdump (str, x.data, x.size, "\t\t\t");
1353 adds (str, _("\t\tY:\n"));
1354 _gnutls_buffer_hexdump (str, y.data, y.size, "\t\t\t");
1356 gnutls_free (x.data);
1357 gnutls_free (y.data);
1361 break;
1362 case GNUTLS_PK_DSA:
1364 gnutls_datum_t p, q, g, y;
1366 err = gnutls_pubkey_get_pk_dsa_raw (pubkey, &p, &q, &g, &y);
1367 if (err < 0)
1368 addf (str, "error: get_pk_dsa_raw: %s\n",
1369 gnutls_strerror (err));
1370 else
1372 addf (str, _("\t\tPublic key (bits %d):\n"), bits);
1373 _gnutls_buffer_hexdump (str, y.data, y.size, "\t\t\t");
1374 adds (str, _("\t\tP:\n"));
1375 _gnutls_buffer_hexdump (str, p.data, p.size, "\t\t\t");
1376 adds (str, _("\t\tQ:\n"));
1377 _gnutls_buffer_hexdump (str, q.data, q.size, "\t\t\t");
1378 adds (str, _("\t\tG:\n"));
1379 _gnutls_buffer_hexdump (str, g.data, g.size, "\t\t\t");
1381 gnutls_free (p.data);
1382 gnutls_free (q.data);
1383 gnutls_free (g.data);
1384 gnutls_free (y.data);
1388 break;
1390 default:
1391 break;
1394 gnutls_pubkey_deinit(pubkey);
1398 print_unique_ids (str, cert);
1400 /* Extensions. */
1401 if (gnutls_x509_crt_get_version (cert) >= 3)
1403 cert_type_t ccert;
1405 ccert.crt = cert;
1406 print_extensions (str, "", TYPE_CRT, ccert);
1409 /* Signature. */
1410 if (!notsigned)
1412 int err;
1413 size_t size = 0;
1414 char *buffer = NULL;
1416 err = gnutls_x509_crt_get_signature_algorithm (cert);
1417 if (err < 0)
1418 addf (str, "error: get_signature_algorithm: %s\n",
1419 gnutls_strerror (err));
1420 else
1422 const char *name = gnutls_sign_algorithm_get_name (err);
1423 if (name == NULL)
1424 name = _("unknown");
1425 addf (str, _("\tSignature Algorithm: %s\n"), name);
1427 if (err == GNUTLS_SIGN_RSA_MD5 || err == GNUTLS_SIGN_RSA_MD2)
1429 adds (str, _("warning: signed using a broken signature "
1430 "algorithm that can be forged.\n"));
1433 err = gnutls_x509_crt_get_signature (cert, buffer, &size);
1434 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
1436 addf (str, "error: get_signature: %s\n", gnutls_strerror (err));
1437 return;
1440 buffer = gnutls_malloc (size);
1441 if (!buffer)
1443 addf (str, "error: malloc: %s\n",
1444 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
1445 return;
1448 err = gnutls_x509_crt_get_signature (cert, buffer, &size);
1449 if (err < 0)
1451 gnutls_free (buffer);
1452 addf (str, "error: get_signature2: %s\n", gnutls_strerror (err));
1453 return;
1456 adds (str, _("\tSignature:\n"));
1457 _gnutls_buffer_hexdump (str, buffer, size, "\t\t");
1459 gnutls_free (buffer);
1463 static void
1464 print_fingerprint (gnutls_buffer_st * str, gnutls_x509_crt_t cert,
1465 gnutls_digest_algorithm_t algo)
1467 int err;
1468 char buffer[MAX_HASH_SIZE];
1469 size_t size = sizeof (buffer);
1471 err = gnutls_x509_crt_get_fingerprint (cert, algo, buffer, &size);
1472 if (err < 0)
1474 addf (str, "error: get_fingerprint: %s\n", gnutls_strerror (err));
1475 return;
1478 if (algo == GNUTLS_DIG_MD5)
1479 adds (str, _("\tMD5 fingerprint:\n\t\t"));
1480 else
1481 adds (str, _("\tSHA-1 fingerprint:\n\t\t"));
1482 _gnutls_buffer_hexprint (str, buffer, size);
1483 adds (str, "\n");
1486 static void
1487 print_keyid (gnutls_buffer_st * str, gnutls_x509_crt_t cert)
1489 int err;
1490 unsigned char buffer[32];
1491 size_t size = sizeof(buffer);
1492 const char* name;
1493 char* p;
1494 unsigned int bits;
1496 err = gnutls_x509_crt_get_key_id (cert, 0, buffer, &size);
1497 if (err < 0)
1499 addf (str, "error: get_key_id: %s\n", gnutls_strerror (err));
1500 return;
1503 adds (str, _("\tPublic Key Id:\n\t\t"));
1504 _gnutls_buffer_hexprint (str, buffer, size);
1505 adds (str, "\n");
1507 err = gnutls_x509_crt_get_pk_algorithm (cert, &bits);
1508 if (err < 0)
1509 return;
1511 name = gnutls_pk_get_name(err);
1512 if (name == NULL)
1513 return;
1515 p = _gnutls_key_fingerprint_randomart(buffer, size, name, bits, "\t\t");
1516 if (p == NULL)
1517 return;
1519 adds (str, _("\tPublic key's random art:\n"));
1520 adds (str, p);
1521 adds (str, "\n");
1523 gnutls_free(p);
1526 static void
1527 print_other (gnutls_buffer_st * str, gnutls_x509_crt_t cert, int notsigned)
1529 if (!notsigned)
1531 print_fingerprint (str, cert, GNUTLS_DIG_SHA1);
1533 print_keyid (str, cert);
1536 static void
1537 print_oneline (gnutls_buffer_st * str, gnutls_x509_crt_t cert)
1539 /* Subject. */
1541 char *dn;
1542 size_t dn_size = 0;
1543 int err;
1545 err = gnutls_x509_crt_get_dn (cert, NULL, &dn_size);
1546 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
1547 addf (str, "unknown subject (%s), ", gnutls_strerror (err));
1548 else
1550 dn = gnutls_malloc (dn_size);
1551 if (!dn)
1552 addf (str, "unknown subject (%s), ",
1553 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
1554 else
1556 err = gnutls_x509_crt_get_dn (cert, dn, &dn_size);
1557 if (err < 0)
1558 addf (str, "unknown subject (%s), ", gnutls_strerror (err));
1559 else
1560 addf (str, "subject `%s', ", dn);
1561 gnutls_free (dn);
1566 /* Issuer. */
1568 char *dn;
1569 size_t dn_size = 0;
1570 int err;
1572 err = gnutls_x509_crt_get_issuer_dn (cert, NULL, &dn_size);
1573 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
1574 addf (str, "unknown issuer (%s), ", gnutls_strerror (err));
1575 else
1577 dn = gnutls_malloc (dn_size);
1578 if (!dn)
1579 addf (str, "unknown issuer (%s), ",
1580 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
1581 else
1583 err = gnutls_x509_crt_get_issuer_dn (cert, dn, &dn_size);
1584 if (err < 0)
1585 addf (str, "unknown issuer (%s), ", gnutls_strerror (err));
1586 else
1587 addf (str, "issuer `%s', ", dn);
1588 gnutls_free (dn);
1593 /* Key algorithm and size. */
1595 unsigned int bits;
1596 const char *name = gnutls_pk_algorithm_get_name
1597 (gnutls_x509_crt_get_pk_algorithm (cert, &bits));
1598 if (name == NULL)
1599 name = "Unknown";
1600 addf (str, "%s key %d bits, ", name, bits);
1603 /* Signature Algorithm. */
1605 int err;
1607 err = gnutls_x509_crt_get_signature_algorithm (cert);
1608 if (err < 0)
1609 addf (str, "unknown signature algorithm (%s), ", gnutls_strerror (err));
1610 else
1612 const char *name = gnutls_sign_algorithm_get_name (err);
1613 if (name == NULL)
1614 name = _("unknown");
1615 if (err == GNUTLS_SIGN_RSA_MD5 || err == GNUTLS_SIGN_RSA_MD2)
1616 addf (str, _("signed using %s (broken!), "), name);
1617 else
1618 addf (str, _("signed using %s, "), name);
1622 /* Validity. */
1624 time_t tim;
1626 tim = gnutls_x509_crt_get_activation_time (cert);
1628 char s[42];
1629 size_t max = sizeof (s);
1630 struct tm t;
1632 if (gmtime_r (&tim, &t) == NULL)
1633 addf (str, "unknown activation (%ld), ", (unsigned long) tim);
1634 else if (strftime (s, max, "%Y-%m-%d %H:%M:%S UTC", &t) == 0)
1635 addf (str, "failed activation (%ld), ", (unsigned long) tim);
1636 else
1637 addf (str, "activated `%s', ", s);
1640 tim = gnutls_x509_crt_get_expiration_time (cert);
1642 char s[42];
1643 size_t max = sizeof (s);
1644 struct tm t;
1646 if (gmtime_r (&tim, &t) == NULL)
1647 addf (str, "unknown expiry (%ld), ", (unsigned long) tim);
1648 else if (strftime (s, max, "%Y-%m-%d %H:%M:%S UTC", &t) == 0)
1649 addf (str, "failed expiry (%ld), ", (unsigned long) tim);
1650 else
1651 addf (str, "expires `%s', ", s);
1656 int pathlen;
1657 char *policyLanguage;
1658 int err;
1660 err = gnutls_x509_crt_get_proxy (cert, NULL,
1661 &pathlen, &policyLanguage, NULL, NULL);
1662 if (err == 0)
1664 addf (str, "proxy certificate (policy=");
1665 if (strcmp (policyLanguage, "1.3.6.1.5.5.7.21.1") == 0)
1666 addf (str, "id-ppl-inheritALL");
1667 else if (strcmp (policyLanguage, "1.3.6.1.5.5.7.21.2") == 0)
1668 addf (str, "id-ppl-independent");
1669 else
1670 addf (str, "%s", policyLanguage);
1671 if (pathlen >= 0)
1672 addf (str, ", pathlen=%d), ", pathlen);
1673 else
1674 addf (str, "), ");
1675 gnutls_free (policyLanguage);
1680 char buffer[20];
1681 size_t size = sizeof (buffer);
1682 int err;
1684 err = gnutls_x509_crt_get_fingerprint (cert, GNUTLS_DIG_SHA1,
1685 buffer, &size);
1686 if (err < 0)
1688 addf (str, "unknown fingerprint (%s)", gnutls_strerror (err));
1690 else
1692 addf (str, "SHA-1 fingerprint `");
1693 _gnutls_buffer_hexprint (str, buffer, size);
1694 adds (str, "'");
1701 * gnutls_x509_crt_print:
1702 * @cert: The structure to be printed
1703 * @format: Indicate the format to use
1704 * @out: Newly allocated datum with (0) terminated string.
1706 * This function will pretty print a X.509 certificate, suitable for
1707 * display to a human.
1709 * If the format is %GNUTLS_CRT_PRINT_FULL then all fields of the
1710 * certificate will be output, on multiple lines. The
1711 * %GNUTLS_CRT_PRINT_ONELINE format will generate one line with some
1712 * selected fields, which is useful for logging purposes.
1714 * The output @out needs to be deallocate using gnutls_free().
1716 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1717 * negative error value.
1720 gnutls_x509_crt_print (gnutls_x509_crt_t cert,
1721 gnutls_certificate_print_formats_t format,
1722 gnutls_datum_t * out)
1724 gnutls_buffer_st str;
1725 int ret;
1727 if (format == GNUTLS_CRT_PRINT_FULL
1728 || format == GNUTLS_CRT_PRINT_UNSIGNED_FULL)
1730 _gnutls_buffer_init (&str);
1732 _gnutls_buffer_append_str (&str, _("X.509 Certificate Information:\n"));
1734 print_cert (&str, cert, format == GNUTLS_CRT_PRINT_UNSIGNED_FULL);
1736 _gnutls_buffer_append_str (&str, _("Other Information:\n"));
1738 print_other (&str, cert, format == GNUTLS_CRT_PRINT_UNSIGNED_FULL);
1740 _gnutls_buffer_append_data (&str, "\0", 1);
1742 ret = _gnutls_buffer_to_datum( &str, out);
1743 if (out->size > 0) out->size--;
1745 return ret;
1747 else if (format == GNUTLS_CRT_PRINT_COMPACT)
1749 _gnutls_buffer_init (&str);
1751 print_oneline (&str, cert);
1753 _gnutls_buffer_append_data (&str, "\n", 1);
1754 print_keyid (&str, cert);
1756 _gnutls_buffer_append_data (&str, "\0", 1);
1758 ret = _gnutls_buffer_to_datum( &str, out);
1759 if (out->size > 0) out->size--;
1761 return ret;
1763 else if (format == GNUTLS_CRT_PRINT_ONELINE)
1765 _gnutls_buffer_init (&str);
1767 print_oneline (&str, cert);
1769 _gnutls_buffer_append_data (&str, "\0", 1);
1771 ret = _gnutls_buffer_to_datum( &str, out);
1772 if (out->size > 0) out->size--;
1774 return ret;
1776 else
1778 gnutls_assert ();
1779 return GNUTLS_E_INVALID_REQUEST;
1783 static void
1784 print_crl (gnutls_buffer_st * str, gnutls_x509_crl_t crl, int notsigned)
1786 /* Version. */
1788 int version = gnutls_x509_crl_get_version (crl);
1789 if (version == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
1790 adds (str, _("\tVersion: 1 (default)\n"));
1791 else if (version < 0)
1792 addf (str, "error: get_version: %s\n", gnutls_strerror (version));
1793 else
1794 addf (str, _("\tVersion: %d\n"), version);
1797 /* Issuer. */
1798 if (!notsigned)
1800 char *dn;
1801 size_t dn_size = 0;
1802 int err;
1804 err = gnutls_x509_crl_get_issuer_dn (crl, NULL, &dn_size);
1805 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
1806 addf (str, "error: get_issuer_dn: %s\n", gnutls_strerror (err));
1807 else
1809 dn = gnutls_malloc (dn_size);
1810 if (!dn)
1811 addf (str, "error: malloc (%d): %s\n", (int) dn_size,
1812 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
1813 else
1815 err = gnutls_x509_crl_get_issuer_dn (crl, dn, &dn_size);
1816 if (err < 0)
1817 addf (str, "error: get_issuer_dn: %s\n",
1818 gnutls_strerror (err));
1819 else
1820 addf (str, _("\tIssuer: %s\n"), dn);
1822 gnutls_free (dn);
1826 /* Validity. */
1828 time_t tim;
1830 adds (str, _("\tUpdate dates:\n"));
1832 tim = gnutls_x509_crl_get_this_update (crl);
1834 char s[42];
1835 size_t max = sizeof (s);
1836 struct tm t;
1838 if (gmtime_r (&tim, &t) == NULL)
1839 addf (str, "error: gmtime_r (%ld)\n", (unsigned long) tim);
1840 else if (strftime (s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0)
1841 addf (str, "error: strftime (%ld)\n", (unsigned long) tim);
1842 else
1843 addf (str, _("\t\tIssued: %s\n"), s);
1846 tim = gnutls_x509_crl_get_next_update (crl);
1848 char s[42];
1849 size_t max = sizeof (s);
1850 struct tm t;
1852 if (tim == -1)
1853 addf (str, "\t\tNo next update time.\n");
1854 else if (gmtime_r (&tim, &t) == NULL)
1855 addf (str, "error: gmtime_r (%ld)\n", (unsigned long) tim);
1856 else if (strftime (s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0)
1857 addf (str, "error: strftime (%ld)\n", (unsigned long) tim);
1858 else
1859 addf (str, _("\t\tNext at: %s\n"), s);
1863 /* Extensions. */
1864 if (gnutls_x509_crl_get_version (crl) >= 2)
1866 size_t i;
1867 int err = 0;
1868 int aki_idx = 0;
1869 int crl_nr = 0;
1871 for (i = 0;; i++)
1873 char oid[MAX_OID_SIZE] = "";
1874 size_t sizeof_oid = sizeof (oid);
1875 unsigned int critical;
1877 err = gnutls_x509_crl_get_extension_info (crl, i,
1878 oid, &sizeof_oid,
1879 &critical);
1880 if (err < 0)
1882 if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
1883 break;
1884 addf (str, "error: get_extension_info: %s\n",
1885 gnutls_strerror (err));
1886 continue;
1889 if (i == 0)
1890 adds (str, _("\tExtensions:\n"));
1892 if (strcmp (oid, "2.5.29.20") == 0)
1894 char nr[128];
1895 size_t nr_size = sizeof (nr);
1897 if (crl_nr)
1899 addf (str, "error: more than one CRL number\n");
1900 continue;
1903 err = gnutls_x509_crl_get_number (crl, nr, &nr_size, &critical);
1905 addf (str, _("\t\tCRL Number (%s): "),
1906 critical ? _("critical") : _("not critical"));
1908 if (err < 0)
1909 addf (str, "error: get_number: %s\n", gnutls_strerror (err));
1910 else
1912 _gnutls_buffer_hexprint (str, nr, nr_size);
1913 addf (str, "\n");
1916 crl_nr++;
1918 else if (strcmp (oid, "2.5.29.35") == 0)
1920 cert_type_t ccert;
1922 if (aki_idx)
1924 addf (str, "error: more than one AKI extension\n");
1925 continue;
1928 addf (str, _("\t\tAuthority Key Identifier (%s):\n"),
1929 critical ? _("critical") : _("not critical"));
1931 ccert.crl = crl;
1932 print_aki (str, TYPE_CRL, ccert);
1934 aki_idx++;
1936 else
1938 char *buffer;
1939 size_t extlen = 0;
1941 addf (str, _("\t\tUnknown extension %s (%s):\n"), oid,
1942 critical ? _("critical") : _("not critical"));
1944 err = gnutls_x509_crl_get_extension_data (crl, i,
1945 NULL, &extlen);
1946 if (err < 0)
1948 addf (str, "error: get_extension_data: %s\n",
1949 gnutls_strerror (err));
1950 continue;
1953 buffer = gnutls_malloc (extlen);
1954 if (!buffer)
1956 addf (str, "error: malloc: %s\n",
1957 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
1958 continue;
1961 err = gnutls_x509_crl_get_extension_data (crl, i,
1962 buffer, &extlen);
1963 if (err < 0)
1965 gnutls_free (buffer);
1966 addf (str, "error: get_extension_data2: %s\n",
1967 gnutls_strerror (err));
1968 continue;
1971 adds (str, _("\t\t\tASCII: "));
1972 _gnutls_buffer_asciiprint (str, buffer, extlen);
1973 adds (str, "\n");
1975 adds (str, _("\t\t\tHexdump: "));
1976 _gnutls_buffer_hexprint (str, buffer, extlen);
1977 adds (str, "\n");
1979 gnutls_free (buffer);
1985 /* Revoked certificates. */
1987 int num = gnutls_x509_crl_get_crt_count (crl);
1988 int j;
1990 if (num)
1991 addf (str, _("\tRevoked certificates (%d):\n"), num);
1992 else
1993 adds (str, _("\tNo revoked certificates.\n"));
1995 for (j = 0; j < num; j++)
1997 unsigned char serial[128];
1998 size_t serial_size = sizeof (serial);
1999 int err;
2000 time_t tim;
2002 err = gnutls_x509_crl_get_crt_serial (crl, j, serial,
2003 &serial_size, &tim);
2004 if (err < 0)
2005 addf (str, "error: get_crt_serial: %s\n", gnutls_strerror (err));
2006 else
2008 char s[42];
2009 size_t max = sizeof (s);
2010 struct tm t;
2012 adds (str, _("\t\tSerial Number (hex): "));
2013 _gnutls_buffer_hexprint (str, serial, serial_size);
2014 adds (str, "\n");
2016 if (gmtime_r (&tim, &t) == NULL)
2017 addf (str, "error: gmtime_r (%ld)\n", (unsigned long) tim);
2018 else if (strftime (s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0)
2019 addf (str, "error: strftime (%ld)\n", (unsigned long) tim);
2020 else
2021 addf (str, _("\t\tRevoked at: %s\n"), s);
2026 /* Signature. */
2027 if (!notsigned)
2029 int err;
2030 size_t size = 0;
2031 char *buffer = NULL;
2033 err = gnutls_x509_crl_get_signature_algorithm (crl);
2034 if (err < 0)
2035 addf (str, "error: get_signature_algorithm: %s\n",
2036 gnutls_strerror (err));
2037 else
2039 const char *name = gnutls_sign_algorithm_get_name (err);
2040 if (name == NULL)
2041 name = _("unknown");
2042 addf (str, _("\tSignature Algorithm: %s\n"), name);
2044 if (err == GNUTLS_SIGN_RSA_MD5 || err == GNUTLS_SIGN_RSA_MD2)
2046 adds (str, _("warning: signed using a broken signature "
2047 "algorithm that can be forged.\n"));
2050 err = gnutls_x509_crl_get_signature (crl, buffer, &size);
2051 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
2053 addf (str, "error: get_signature: %s\n", gnutls_strerror (err));
2054 return;
2057 buffer = gnutls_malloc (size);
2058 if (!buffer)
2060 addf (str, "error: malloc: %s\n",
2061 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
2062 return;
2065 err = gnutls_x509_crl_get_signature (crl, buffer, &size);
2066 if (err < 0)
2068 gnutls_free (buffer);
2069 addf (str, "error: get_signature2: %s\n", gnutls_strerror (err));
2070 return;
2073 adds (str, _("\tSignature:\n"));
2074 _gnutls_buffer_hexdump (str, buffer, size, "\t\t");
2076 gnutls_free (buffer);
2081 * gnutls_x509_crl_print:
2082 * @crl: The structure to be printed
2083 * @format: Indicate the format to use
2084 * @out: Newly allocated datum with (0) terminated string.
2086 * This function will pretty print a X.509 certificate revocation
2087 * list, suitable for display to a human.
2089 * The output @out needs to be deallocate using gnutls_free().
2091 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2092 * negative error value.
2095 gnutls_x509_crl_print (gnutls_x509_crl_t crl,
2096 gnutls_certificate_print_formats_t format,
2097 gnutls_datum_t * out)
2099 gnutls_buffer_st str;
2100 int ret;
2102 _gnutls_buffer_init (&str);
2104 _gnutls_buffer_append_str
2105 (&str, _("X.509 Certificate Revocation List Information:\n"));
2107 print_crl (&str, crl, format == GNUTLS_CRT_PRINT_UNSIGNED_FULL);
2109 _gnutls_buffer_append_data (&str, "\0", 1);
2111 ret = _gnutls_buffer_to_datum( &str, out);
2112 if (out->size > 0) out->size--;
2114 return ret;
2117 static void
2118 print_crq (gnutls_buffer_st * str, gnutls_x509_crq_t cert)
2120 /* Version. */
2122 int version = gnutls_x509_crq_get_version (cert);
2123 if (version < 0)
2124 addf (str, "error: get_version: %s\n", gnutls_strerror (version));
2125 else
2126 addf (str, _("\tVersion: %d\n"), version);
2129 /* Subject */
2131 char *dn;
2132 size_t dn_size = 0;
2133 int err;
2135 err = gnutls_x509_crq_get_dn (cert, NULL, &dn_size);
2136 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
2137 addf (str, "error: get_dn: %s\n", gnutls_strerror (err));
2138 else
2140 dn = gnutls_malloc (dn_size);
2141 if (!dn)
2142 addf (str, "error: malloc (%d): %s\n", (int) dn_size,
2143 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
2144 else
2146 err = gnutls_x509_crq_get_dn (cert, dn, &dn_size);
2147 if (err < 0)
2148 addf (str, "error: get_dn: %s\n", gnutls_strerror (err));
2149 else
2150 addf (str, _("\tSubject: %s\n"), dn);
2151 gnutls_free (dn);
2156 /* SubjectPublicKeyInfo. */
2158 int err;
2159 unsigned int bits;
2161 err = gnutls_x509_crq_get_pk_algorithm (cert, &bits);
2162 if (err < 0)
2163 addf (str, "error: get_pk_algorithm: %s\n", gnutls_strerror (err));
2164 else
2166 const char *name = gnutls_pk_algorithm_get_name (err);
2167 if (name == NULL)
2168 name = _("unknown");
2170 addf (str, _("\tSubject Public Key Algorithm: %s\n"), name);
2171 switch (err)
2173 case GNUTLS_PK_RSA:
2175 gnutls_datum_t m, e;
2177 err = gnutls_x509_crq_get_key_rsa_raw (cert, &m, &e);
2178 if (err < 0)
2179 addf (str, "error: get_pk_rsa_raw: %s\n",
2180 gnutls_strerror (err));
2181 else
2183 addf (str, _("\t\tModulus (bits %d):\n"), bits);
2184 _gnutls_buffer_hexdump (str, m.data, m.size, "\t\t\t");
2185 adds (str, _("\t\tExponent:\n"));
2186 _gnutls_buffer_hexdump (str, e.data, e.size, "\t\t\t");
2188 gnutls_free (m.data);
2189 gnutls_free (e.data);
2193 break;
2194 #if 0 /* not implemented yet */
2195 case GNUTLS_PK_DSA:
2197 gnutls_datum_t p, q, g, y;
2199 err = gnutls_x509_crq_get_key_dsa_raw (cert, &p, &q, &g, &y);
2200 if (err < 0)
2201 addf (str, "error: get_pk_dsa_raw: %s\n",
2202 gnutls_strerror (err));
2203 else
2205 addf (str, _("\t\tPublic key (bits %d):\n"), bits);
2206 _gnutls_buffer_hexdump (str, y.data, y.size, "\t\t\t");
2207 addf (str, _("\t\tP:\n"));
2208 _gnutls_buffer_hexdump (str, p.data, p.size, "\t\t\t");
2209 addf (str, _("\t\tQ:\n"));
2210 _gnutls_buffer_hexdump (str, q.data, q.size, "\t\t\t");
2211 addf (str, _("\t\tG:\n"));
2212 _gnutls_buffer_hexdump (str, g.data, g.size, "\t\t\t");
2214 gnutls_free (p.data);
2215 gnutls_free (q.data);
2216 gnutls_free (g.data);
2217 gnutls_free (y.data);
2221 break;
2222 #endif
2223 default:
2224 break;
2229 /* parse attributes */
2231 size_t i;
2232 int err = 0;
2233 int extensions = 0;
2234 int challenge = 0;
2236 for (i = 0;; i++)
2238 char oid[MAX_OID_SIZE] = "";
2239 size_t sizeof_oid = sizeof (oid);
2241 err = gnutls_x509_crq_get_attribute_info (cert, i, oid, &sizeof_oid);
2242 if (err < 0)
2244 if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
2245 break;
2246 addf (str, "error: get_extension_info: %s\n",
2247 gnutls_strerror (err));
2248 continue;
2251 if (i == 0)
2252 adds (str, _("\tAttributes:\n"));
2254 if (strcmp (oid, "1.2.840.113549.1.9.14") == 0)
2256 cert_type_t ccert;
2258 if (extensions)
2260 addf (str, "error: more than one extensionsRequest\n");
2261 continue;
2264 ccert.crq = cert;
2265 print_extensions (str, "\t", TYPE_CRQ, ccert);
2267 extensions++;
2269 else if (strcmp (oid, "1.2.840.113549.1.9.7") == 0)
2271 char *pass;
2272 size_t size;
2274 if (challenge)
2276 adds (str,
2277 "error: more than one Challenge password attribute\n");
2278 continue;
2281 err = gnutls_x509_crq_get_challenge_password (cert, NULL, &size);
2282 if (err < 0)
2284 addf (str, "error: get_challenge_password: %s\n",
2285 gnutls_strerror (err));
2286 continue;
2289 size++;
2291 pass = gnutls_malloc (size);
2292 if (!pass)
2294 addf (str, "error: malloc: %s\n",
2295 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
2296 continue;
2299 err = gnutls_x509_crq_get_challenge_password (cert, pass, &size);
2300 if (err < 0)
2301 addf (str, "error: get_challenge_password: %s\n",
2302 gnutls_strerror (err));
2303 else
2304 addf (str, _("\t\tChallenge password: %s\n"), pass);
2306 gnutls_free (pass);
2308 challenge++;
2310 else
2312 char *buffer;
2313 size_t extlen = 0;
2315 addf (str, _("\t\tUnknown attribute %s:\n"), oid);
2317 err = gnutls_x509_crq_get_attribute_data (cert, i, NULL, &extlen);
2318 if (err < 0)
2320 addf (str, "error: get_attribute_data: %s\n",
2321 gnutls_strerror (err));
2322 continue;
2325 buffer = gnutls_malloc (extlen);
2326 if (!buffer)
2328 addf (str, "error: malloc: %s\n",
2329 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
2330 continue;
2333 err = gnutls_x509_crq_get_attribute_data (cert, i,
2334 buffer, &extlen);
2335 if (err < 0)
2337 gnutls_free (buffer);
2338 addf (str, "error: get_attribute_data2: %s\n",
2339 gnutls_strerror (err));
2340 continue;
2343 adds (str, _("\t\t\tASCII: "));
2344 _gnutls_buffer_asciiprint (str, buffer, extlen);
2345 adds (str, "\n");
2347 adds (str, _("\t\t\tHexdump: "));
2348 _gnutls_buffer_hexprint (str, buffer, extlen);
2349 adds (str, "\n");
2351 gnutls_free (buffer);
2357 static void
2358 print_crq_other (gnutls_buffer_st * str, gnutls_x509_crq_t crq)
2360 int err;
2361 size_t size = 0;
2362 unsigned char *buffer = NULL;
2364 err = gnutls_x509_crq_get_key_id (crq, 0, buffer, &size);
2365 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
2367 addf (str, "error: get_key_id: %s\n", gnutls_strerror (err));
2368 return;
2371 buffer = gnutls_malloc (size);
2372 if (!buffer)
2374 addf (str, "error: malloc: %s\n",
2375 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
2376 return;
2379 err = gnutls_x509_crq_get_key_id (crq, 0, buffer, &size);
2380 if (err < 0)
2382 gnutls_free (buffer);
2383 addf (str, "error: get_key_id2: %s\n", gnutls_strerror (err));
2384 return;
2387 adds (str, _("\tPublic Key Id:\n\t\t"));
2388 _gnutls_buffer_hexprint (str, buffer, size);
2389 adds (str, "\n");
2391 gnutls_free (buffer);
2395 * gnutls_x509_crq_print:
2396 * @crq: The structure to be printed
2397 * @format: Indicate the format to use
2398 * @out: Newly allocated datum with (0) terminated string.
2400 * This function will pretty print a certificate request, suitable for
2401 * display to a human.
2403 * The output @out needs to be deallocate using gnutls_free().
2405 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2406 * negative error value.
2408 * Since: 2.8.0
2411 gnutls_x509_crq_print (gnutls_x509_crq_t crq,
2412 gnutls_certificate_print_formats_t format,
2413 gnutls_datum_t * out)
2415 gnutls_buffer_st str;
2416 int ret;
2418 _gnutls_buffer_init (&str);
2420 _gnutls_buffer_append_str
2421 (&str, _("PKCS #10 Certificate Request Information:\n"));
2423 print_crq (&str, crq);
2425 _gnutls_buffer_append_str (&str, _("Other Information:\n"));
2427 print_crq_other (&str, crq);
2429 _gnutls_buffer_append_data (&str, "\0", 1);
2431 ret = _gnutls_buffer_to_datum( &str, out);
2432 if (out->size > 0) out->size--;
2434 return ret;