Corrected bugs in record parsing.
[gnutls.git] / lib / x509 / output.c
blobb3657d7e19cf5fc6d267af28c6aef74ad130819b
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 #define addf _gnutls_buffer_append_printf
35 #define adds _gnutls_buffer_append_str
37 #define ERROR_STR (char*) "(error)"
39 static char *
40 ip_to_string (void *_ip, int ip_size, char *string, int string_size)
42 uint8_t *ip;
44 if (ip_size != 4 && ip_size != 16)
46 gnutls_assert ();
47 return NULL;
50 if (ip_size == 4 && string_size < 16)
52 gnutls_assert ();
53 return NULL;
56 if (ip_size == 16 && string_size < 48)
58 gnutls_assert ();
59 return NULL;
62 ip = _ip;
63 switch (ip_size)
65 case 4:
66 snprintf (string, string_size, "%u.%u.%u.%u", ip[0], ip[1], ip[2],
67 ip[3]);
68 break;
69 case 16:
70 snprintf (string, string_size, "%x:%x:%x:%x:%x:%x:%x:%x",
71 (ip[0] << 8) | ip[1], (ip[2] << 8) | ip[3],
72 (ip[4] << 8) | ip[5], (ip[6] << 8) | ip[7],
73 (ip[8] << 8) | ip[9], (ip[10] << 8) | ip[11],
74 (ip[12] << 8) | ip[13], (ip[14] << 8) | ip[15]);
75 break;
78 return string;
81 static void
82 add_altname (gnutls_buffer_st * str, const char *prefix,
83 unsigned int alt_type, char *name, size_t name_size)
85 char str_ip[64];
86 char *p;
88 if ((alt_type == GNUTLS_SAN_DNSNAME
89 || alt_type == GNUTLS_SAN_RFC822NAME
90 || alt_type == GNUTLS_SAN_URI) && strlen (name) != name_size)
92 adds (str, _("warning: altname contains an embedded NUL, "
93 "replacing with '!'\n"));
94 while (strlen (name) < name_size)
95 name[strlen (name)] = '!';
98 switch (alt_type)
100 case GNUTLS_SAN_DNSNAME:
101 addf (str, "%s\t\t\tDNSname: %.*s\n", prefix, (int) name_size, name);
102 break;
104 case GNUTLS_SAN_RFC822NAME:
105 addf (str, "%s\t\t\tRFC822name: %.*s\n", prefix, (int) name_size, name);
106 break;
108 case GNUTLS_SAN_URI:
109 addf (str, "%s\t\t\tURI: %.*s\n", prefix, (int) name_size, name);
110 break;
112 case GNUTLS_SAN_IPADDRESS:
113 p = ip_to_string (name, name_size, str_ip, sizeof (str_ip));
114 if (p == NULL)
115 p = ERROR_STR;
116 addf (str, "%s\t\t\tIPAddress: %s\n", prefix, p);
117 break;
119 case GNUTLS_SAN_DN:
120 addf (str, "%s\t\t\tdirectoryName: %.*s\n", prefix,
121 (int) name_size, name);
122 break;
123 default:
124 addf (str, "error: unknown altname\n");
125 break;
129 static void
130 print_proxy (gnutls_buffer_st * str, gnutls_x509_crt_t cert)
132 int pathlen;
133 char *policyLanguage;
134 char *policy;
135 size_t npolicy;
136 int err;
138 err = gnutls_x509_crt_get_proxy (cert, NULL,
139 &pathlen, &policyLanguage,
140 &policy, &npolicy);
141 if (err < 0)
143 addf (str, "error: get_proxy: %s\n", gnutls_strerror (err));
144 return;
147 if (pathlen >= 0)
148 addf (str, _("\t\t\tPath Length Constraint: %d\n"), pathlen);
149 addf (str, _("\t\t\tPolicy Language: %s"), policyLanguage);
150 if (strcmp (policyLanguage, "1.3.6.1.5.5.7.21.1") == 0)
151 adds (str, " (id-ppl-inheritALL)\n");
152 else if (strcmp (policyLanguage, "1.3.6.1.5.5.7.21.2") == 0)
153 adds (str, " (id-ppl-independent)\n");
154 else
155 adds (str, "\n");
156 if (npolicy)
158 adds (str, _("\t\t\tPolicy:\n\t\t\t\tASCII: "));
159 _gnutls_buffer_asciiprint (str, policy, npolicy);
160 adds (str, _("\n\t\t\t\tHexdump: "));
161 _gnutls_buffer_hexprint (str, policy, npolicy);
162 adds (str, "\n");
166 static void
167 print_aia (gnutls_buffer_st * str, gnutls_x509_crt_t cert)
169 int err;
170 int seq = 0;
171 gnutls_datum_t data;
173 for (;;)
175 err = gnutls_x509_crt_get_authority_info_access
176 (cert, seq, GNUTLS_IA_ACCESSMETHOD_OID, &data, NULL);
177 if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
178 return;
179 if (err < 0)
181 addf (str, "error: get_aia: %s\n", gnutls_strerror (err));
182 return;
185 addf (str, _("\t\t\tAccess Method: %.*s"), data.size, data.data);
186 if (data.size == sizeof (GNUTLS_OID_AD_OCSP) &&
187 memcmp (data.data, GNUTLS_OID_AD_OCSP, data.size) == 0)
188 adds (str, " (id-ad-ocsp)\n");
189 else if (data.size == sizeof (GNUTLS_OID_AD_CAISSUERS) &&
190 memcmp (data.data, GNUTLS_OID_AD_CAISSUERS, data.size) == 0)
191 adds (str, " (id-ad-caIssuers)\n");
192 else
193 adds (str, " (UNKNOWN)\n");
195 err = gnutls_x509_crt_get_authority_info_access
196 (cert, seq, GNUTLS_IA_ACCESSLOCATION_GENERALNAME_TYPE, &data, NULL);
197 if (err < 0)
199 addf (str, "error: get_aia type: %s\n", gnutls_strerror (err));
200 return;
203 if (data.size == sizeof ("uniformResourceIdentifier") &&
204 memcmp (data.data, "uniformResourceIdentifier", data.size) == 0)
206 adds (str, "\t\t\tAccess Location URI: ");
207 err = gnutls_x509_crt_get_authority_info_access
208 (cert, seq, GNUTLS_IA_URI, &data, NULL);
209 if (err < 0)
211 addf (str, "error: get_aia uri: %s\n", gnutls_strerror (err));
212 return;
214 addf (str, "%.*s\n", data.size, data.data);
216 else
217 adds (str, "\t\t\tUnsupported accessLocation type\n");
219 seq++;
223 static void
224 print_ski (gnutls_buffer_st * str, gnutls_x509_crt_t cert)
226 char *buffer = NULL;
227 size_t size = 0;
228 int err;
230 err = gnutls_x509_crt_get_subject_key_id (cert, buffer, &size, NULL);
231 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
233 addf (str, "error: get_subject_key_id: %s\n", gnutls_strerror (err));
234 return;
237 buffer = gnutls_malloc (size);
238 if (!buffer)
240 addf (str, "error: malloc: %s\n",
241 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
242 return;
245 err = gnutls_x509_crt_get_subject_key_id (cert, buffer, &size, NULL);
246 if (err < 0)
248 gnutls_free (buffer);
249 addf (str, "error: get_subject_key_id2: %s\n", gnutls_strerror (err));
250 return;
253 adds (str, "\t\t\t");
254 _gnutls_buffer_hexprint (str, buffer, size);
255 adds (str, "\n");
257 gnutls_free (buffer);
260 #define TYPE_CRL 1
261 #define TYPE_CRT 2
262 #define TYPE_CRQ 3
263 #define TYPE_PUBKEY 4
265 #define TYPE_CRT_SAN TYPE_CRT
266 #define TYPE_CRQ_SAN TYPE_CRQ
267 #define TYPE_CRT_IAN 4
269 typedef union
271 gnutls_x509_crt_t crt;
272 gnutls_x509_crq_t crq;
273 gnutls_x509_crl_t crl;
274 gnutls_pubkey_t pubkey;
275 } cert_type_t;
277 static void
278 print_aki_gn_serial (gnutls_buffer_st * str, int type, cert_type_t cert)
280 char *buffer = NULL;
281 char serial[128];
282 size_t size = 0, serial_size = sizeof (serial);
283 unsigned int alt_type;
284 int err;
286 if (type == TYPE_CRT)
287 err =
288 gnutls_x509_crt_get_authority_key_gn_serial (cert.crt, 0, NULL, &size,
289 &alt_type, serial,
290 &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,
295 &serial_size, NULL);
296 else
298 gnutls_assert ();
299 return;
302 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
304 addf (str, "error: get_authority_key_gn_serial: %s\n",
305 gnutls_strerror (err));
306 return;
309 buffer = gnutls_malloc (size);
310 if (!buffer)
312 addf (str, "error: malloc: %s\n",
313 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
314 return;
317 if (type == TYPE_CRT)
318 err =
319 gnutls_x509_crt_get_authority_key_gn_serial (cert.crt, 0, buffer, &size,
320 &alt_type, serial,
321 &serial_size, NULL);
322 else
323 err =
324 gnutls_x509_crl_get_authority_key_gn_serial (cert.crl, 0, buffer, &size,
325 &alt_type, serial,
326 &serial_size, NULL);
328 if (err < 0)
330 gnutls_free (buffer);
331 addf (str, "error: get_authority_key_gn_serial2: %s\n",
332 gnutls_strerror (err));
333 return;
336 add_altname (str, "", alt_type, buffer, size);
337 adds (str, "\t\t\tserial: ");
338 _gnutls_buffer_hexprint (str, serial, serial_size);
339 adds (str, "\n");
341 gnutls_free (buffer);
344 static void
345 print_aki (gnutls_buffer_st * str, int type, cert_type_t cert)
347 char *buffer = NULL;
348 size_t size = 0;
349 int err;
351 if (type == TYPE_CRT)
352 err =
353 gnutls_x509_crt_get_authority_key_id (cert.crt, buffer, &size, NULL);
354 else if (type == TYPE_CRL)
355 err =
356 gnutls_x509_crl_get_authority_key_id (cert.crl, buffer, &size, NULL);
357 else
359 gnutls_assert ();
360 return;
363 if (err == GNUTLS_E_X509_UNSUPPORTED_EXTENSION)
365 /* Check if an alternative name is there */
366 print_aki_gn_serial (str, type, cert);
367 return;
370 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
372 addf (str, "error: get_authority_key_id: %s\n", gnutls_strerror (err));
373 return;
376 buffer = gnutls_malloc (size);
377 if (!buffer)
379 addf (str, "error: malloc: %s\n",
380 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
381 return;
384 if (type == TYPE_CRT)
385 err =
386 gnutls_x509_crt_get_authority_key_id (cert.crt, buffer, &size, NULL);
387 else
388 err =
389 gnutls_x509_crl_get_authority_key_id (cert.crl, buffer, &size, NULL);
391 if (err < 0)
393 gnutls_free (buffer);
394 addf (str, "error: get_authority_key_id2: %s\n", gnutls_strerror (err));
395 return;
398 adds (str, "\t\t\t");
399 _gnutls_buffer_hexprint (str, buffer, size);
400 adds (str, "\n");
402 gnutls_free (buffer);
405 static void
406 print_key_usage (gnutls_buffer_st * str, const char *prefix, int type,
407 cert_type_t cert)
409 unsigned int key_usage;
410 int err;
412 if (type == TYPE_CRT)
413 err = gnutls_x509_crt_get_key_usage (cert.crt, &key_usage, NULL);
414 else if (type == TYPE_CRQ)
415 err = gnutls_x509_crq_get_key_usage (cert.crq, &key_usage, NULL);
416 else if (type == TYPE_PUBKEY)
417 err = gnutls_pubkey_get_key_usage (cert.pubkey, &key_usage);
418 else
419 return;
421 if (err < 0)
423 addf (str, "error: get_key_usage: %s\n", gnutls_strerror (err));
424 return;
427 if (key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE)
428 addf (str, _("%sDigital signature.\n"), prefix);
429 if (key_usage & GNUTLS_KEY_NON_REPUDIATION)
430 addf (str, _("%sNon repudiation.\n"), prefix);
431 if (key_usage & GNUTLS_KEY_KEY_ENCIPHERMENT)
432 addf (str, _("%sKey encipherment.\n"), prefix);
433 if (key_usage & GNUTLS_KEY_DATA_ENCIPHERMENT)
434 addf (str, _("%sData encipherment.\n"), prefix);
435 if (key_usage & GNUTLS_KEY_KEY_AGREEMENT)
436 addf (str, _("%sKey agreement.\n"), prefix);
437 if (key_usage & GNUTLS_KEY_KEY_CERT_SIGN)
438 addf (str, _("%sCertificate signing.\n"), prefix);
439 if (key_usage & GNUTLS_KEY_CRL_SIGN)
440 addf (str, _("%sCRL signing.\n"), prefix);
441 if (key_usage & GNUTLS_KEY_ENCIPHER_ONLY)
442 addf (str, _("%sKey encipher only.\n"), prefix);
443 if (key_usage & GNUTLS_KEY_DECIPHER_ONLY)
444 addf (str, _("%sKey decipher only.\n"), prefix);
447 static void
448 print_private_key_usage_period (gnutls_buffer_st * str, const char *prefix,
449 int type, cert_type_t cert)
451 time_t activation, expiration;
452 int err;
453 char s[42];
454 struct tm t;
455 size_t max;
457 if (type == TYPE_CRT)
458 err =
459 gnutls_x509_crt_get_private_key_usage_period (cert.crt, &activation,
460 &expiration, NULL);
461 else if (type == TYPE_CRQ)
462 err =
463 gnutls_x509_crq_get_private_key_usage_period (cert.crq, &activation,
464 &expiration, NULL);
465 else
466 return;
468 if (err < 0)
470 addf (str, "error: get_private_key_usage_period: %s\n",
471 gnutls_strerror (err));
472 return;
475 max = sizeof (s);
477 if (gmtime_r (&activation, &t) == NULL)
478 addf (str, "error: gmtime_r (%ld)\n", (unsigned long) activation);
479 else if (strftime (s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0)
480 addf (str, "error: strftime (%ld)\n", (unsigned long) activation);
481 else
482 addf (str, _("\t\t\tNot Before: %s\n"), s);
484 if (gmtime_r (&expiration, &t) == NULL)
485 addf (str, "error: gmtime_r (%ld)\n", (unsigned long) expiration);
486 else if (strftime (s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0)
487 addf (str, "error: strftime (%ld)\n", (unsigned long) expiration);
488 else
489 addf (str, _("\t\t\tNot After: %s\n"), s);
493 static void
494 print_crldist (gnutls_buffer_st * str, gnutls_x509_crt_t cert)
496 char *buffer = NULL;
497 size_t size;
498 char str_ip[64];
499 char *p;
500 int err;
501 int indx;
503 for (indx = 0;; indx++)
505 size = 0;
506 err = gnutls_x509_crt_get_crl_dist_points (cert, indx, buffer, &size,
507 NULL, NULL);
508 if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
509 return;
510 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
512 addf (str, "error: get_crl_dist_points: %s\n",
513 gnutls_strerror (err));
514 return;
517 buffer = gnutls_malloc (size);
518 if (!buffer)
520 addf (str, "error: malloc: %s\n",
521 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
522 return;
525 err = gnutls_x509_crt_get_crl_dist_points (cert, indx, buffer, &size,
526 NULL, NULL);
527 if (err < 0)
529 gnutls_free (buffer);
530 addf (str, "error: get_crl_dist_points2: %s\n",
531 gnutls_strerror (err));
532 return;
535 if ((err == GNUTLS_SAN_DNSNAME
536 || err == GNUTLS_SAN_RFC822NAME
537 || err == GNUTLS_SAN_URI) && strlen (buffer) != size)
539 adds (str, _("warning: distributionPoint contains an embedded NUL, "
540 "replacing with '!'\n"));
541 while (strlen (buffer) < size)
542 buffer[strlen (buffer)] = '!';
545 switch (err)
547 case GNUTLS_SAN_DNSNAME:
548 addf (str, "\t\t\tDNSname: %.*s\n", (int) size, buffer);
549 break;
551 case GNUTLS_SAN_RFC822NAME:
552 addf (str, "\t\t\tRFC822name: %.*s\n", (int) size, buffer);
553 break;
555 case GNUTLS_SAN_URI:
556 addf (str, "\t\t\tURI: %.*s\n", (int) size, buffer);
557 break;
559 case GNUTLS_SAN_IPADDRESS:
560 p = ip_to_string (buffer, size, str_ip, sizeof (str_ip));
561 if (p == NULL)
562 p = ERROR_STR;
563 addf (str, "\t\t\tIPAddress: %s\n", p);
564 break;
566 case GNUTLS_SAN_DN:
567 addf (str, "\t\t\tdirectoryName: %.*s\n", (int) size, buffer);
568 break;
570 default:
571 addf (str, "error: unknown SAN\n");
572 break;
574 gnutls_free (buffer);
578 static void
579 print_key_purpose (gnutls_buffer_st * str, const char *prefix, int type,
580 cert_type_t cert)
582 int indx;
583 char *buffer = NULL;
584 size_t size;
585 int err;
587 for (indx = 0;; indx++)
589 size = 0;
590 if (type == TYPE_CRT)
591 err = gnutls_x509_crt_get_key_purpose_oid (cert.crt, indx, buffer,
592 &size, NULL);
593 else if (type == TYPE_CRQ)
594 err = gnutls_x509_crq_get_key_purpose_oid (cert.crq, indx, buffer,
595 &size, NULL);
596 else
597 return;
599 if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
600 return;
601 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
603 addf (str, "error: get_key_purpose_oid: %s\n",
604 gnutls_strerror (err));
605 return;
608 buffer = gnutls_malloc (size);
609 if (!buffer)
611 addf (str, "error: malloc: %s\n",
612 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
613 return;
616 if (type == TYPE_CRT)
617 err = gnutls_x509_crt_get_key_purpose_oid (cert.crt, indx, buffer,
618 &size, NULL);
619 else
620 err = gnutls_x509_crq_get_key_purpose_oid (cert.crq, indx, buffer,
621 &size, NULL);
623 if (err < 0)
625 gnutls_free (buffer);
626 addf (str, "error: get_key_purpose_oid2: %s\n",
627 gnutls_strerror (err));
628 return;
631 if (strcmp (buffer, GNUTLS_KP_TLS_WWW_SERVER) == 0)
632 addf (str, _("%s\t\t\tTLS WWW Server.\n"), prefix);
633 else if (strcmp (buffer, GNUTLS_KP_TLS_WWW_CLIENT) == 0)
634 addf (str, _("%s\t\t\tTLS WWW Client.\n"), prefix);
635 else if (strcmp (buffer, GNUTLS_KP_CODE_SIGNING) == 0)
636 addf (str, _("%s\t\t\tCode signing.\n"), prefix);
637 else if (strcmp (buffer, GNUTLS_KP_EMAIL_PROTECTION) == 0)
638 addf (str, _("%s\t\t\tEmail protection.\n"), prefix);
639 else if (strcmp (buffer, GNUTLS_KP_TIME_STAMPING) == 0)
640 addf (str, _("%s\t\t\tTime stamping.\n"), prefix);
641 else if (strcmp (buffer, GNUTLS_KP_OCSP_SIGNING) == 0)
642 addf (str, _("%s\t\t\tOCSP signing.\n"), prefix);
643 else if (strcmp (buffer, GNUTLS_KP_IPSEC_IKE) == 0)
644 addf (str, _("%s\t\t\tIpsec IKE.\n"), prefix);
645 else if (strcmp (buffer, GNUTLS_KP_ANY) == 0)
646 addf (str, _("%s\t\t\tAny purpose.\n"), prefix);
647 else
648 addf (str, "%s\t\t\t%s\n", prefix, buffer);
650 gnutls_free (buffer);
654 static void
655 print_basic (gnutls_buffer_st * str, const char *prefix, int type,
656 cert_type_t cert)
658 int pathlen;
659 int err;
661 if (type == TYPE_CRT)
662 err =
663 gnutls_x509_crt_get_basic_constraints (cert.crt, NULL, NULL, &pathlen);
664 else if (type == TYPE_CRQ)
665 err =
666 gnutls_x509_crq_get_basic_constraints (cert.crq, NULL, NULL, &pathlen);
667 else
668 return;
670 if (err < 0)
672 addf (str, "error: get_basic_constraints: %s\n", gnutls_strerror (err));
673 return;
676 if (err == 0)
677 addf (str, _("%s\t\t\tCertificate Authority (CA): FALSE\n"), prefix);
678 else
679 addf (str, _("%s\t\t\tCertificate Authority (CA): TRUE\n"), prefix);
681 if (pathlen >= 0)
682 addf (str, _("%s\t\t\tPath Length Constraint: %d\n"), prefix, pathlen);
686 static void
687 print_altname (gnutls_buffer_st * str, const char *prefix,
688 unsigned int altname_type, cert_type_t cert)
690 unsigned int altname_idx;
692 for (altname_idx = 0;; altname_idx++)
694 char *buffer = NULL;
695 size_t size = 0;
696 int err;
698 if (altname_type == TYPE_CRT_SAN)
699 err =
700 gnutls_x509_crt_get_subject_alt_name (cert.crt, altname_idx, buffer,
701 &size, NULL);
702 else if (altname_type == TYPE_CRQ_SAN)
703 err =
704 gnutls_x509_crq_get_subject_alt_name (cert.crq, altname_idx, buffer,
705 &size, NULL, NULL);
706 else if (altname_type == TYPE_CRT_IAN)
707 err =
708 gnutls_x509_crt_get_issuer_alt_name (cert.crt, altname_idx, buffer,
709 &size, NULL);
710 else
711 return;
713 if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
714 break;
715 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
717 addf (str, "error: get_subject/issuer_alt_name: %s\n",
718 gnutls_strerror (err));
719 return;
722 buffer = gnutls_malloc (size);
723 if (!buffer)
725 addf (str, "error: malloc: %s\n",
726 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
727 return;
730 if (altname_type == TYPE_CRT_SAN)
731 err =
732 gnutls_x509_crt_get_subject_alt_name (cert.crt, altname_idx, buffer,
733 &size, NULL);
734 else if (altname_type == TYPE_CRQ_SAN)
735 err =
736 gnutls_x509_crq_get_subject_alt_name (cert.crq, altname_idx, buffer,
737 &size, NULL, NULL);
738 else if (altname_type == TYPE_CRT_IAN)
739 err = gnutls_x509_crt_get_issuer_alt_name (cert.crt, altname_idx,
740 buffer, &size, NULL);
742 if (err < 0)
744 gnutls_free (buffer);
745 addf (str, "error: get_subject/issuer_alt_name2: %s\n",
746 gnutls_strerror (err));
747 return;
751 if (err == GNUTLS_SAN_OTHERNAME)
753 char *oid = NULL;
754 size_t oidsize;
756 oidsize = 0;
757 if (altname_type == TYPE_CRT_SAN)
758 err = gnutls_x509_crt_get_subject_alt_othername_oid
759 (cert.crt, altname_idx, oid, &oidsize);
760 else if (altname_type == TYPE_CRQ_SAN)
761 err = gnutls_x509_crq_get_subject_alt_othername_oid
762 (cert.crq, altname_idx, oid, &oidsize);
763 else if (altname_type == TYPE_CRT_IAN)
764 err = gnutls_x509_crt_get_issuer_alt_othername_oid
765 (cert.crt, altname_idx, oid, &oidsize);
767 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
769 gnutls_free (buffer);
770 addf (str,
771 "error: get_subject/issuer_alt_othername_oid: %s\n",
772 gnutls_strerror (err));
773 return;
776 oid = gnutls_malloc (oidsize);
777 if (!oid)
779 gnutls_free (buffer);
780 addf (str, "error: malloc: %s\n",
781 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
782 return;
785 if (altname_type == TYPE_CRT_SAN)
786 err = gnutls_x509_crt_get_subject_alt_othername_oid
787 (cert.crt, altname_idx, oid, &oidsize);
788 else if (altname_type == TYPE_CRQ_SAN)
789 err = gnutls_x509_crq_get_subject_alt_othername_oid
790 (cert.crq, altname_idx, oid, &oidsize);
791 else if (altname_type == TYPE_CRT_IAN)
792 err = gnutls_x509_crt_get_issuer_alt_othername_oid
793 (cert.crt, altname_idx, oid, &oidsize);
795 if (err < 0)
797 gnutls_free (buffer);
798 gnutls_free (oid);
799 addf (str, "error: get_subject_alt_othername_oid2: %s\n",
800 gnutls_strerror (err));
801 return;
804 if (err == GNUTLS_SAN_OTHERNAME_XMPP)
806 if (strlen (buffer) != size)
808 adds (str, _("warning: altname contains an embedded NUL, "
809 "replacing with '!'\n"));
810 while (strlen (buffer) < size)
811 buffer[strlen (buffer)] = '!';
814 addf (str, _("%s\t\t\tXMPP Address: %.*s\n"), prefix,
815 (int) size, buffer);
817 else
819 addf (str, _("%s\t\t\totherName OID: %.*s\n"), prefix,
820 (int) oidsize, oid);
821 addf (str, _("%s\t\t\totherName DER: "), prefix);
822 _gnutls_buffer_hexprint (str, buffer, size);
823 addf (str, _("\n%s\t\t\totherName ASCII: "), prefix);
824 _gnutls_buffer_asciiprint (str, buffer, size);
825 addf (str, "\n");
827 gnutls_free (oid);
829 else
830 add_altname (str, prefix, err, buffer, size);
832 gnutls_free (buffer);
836 static void
837 guiddump (gnutls_buffer_st * str, const char *data, size_t len,
838 const char *spc)
840 size_t j;
842 if (spc)
843 adds (str, spc);
844 addf (str, "{");
845 addf (str, "%.2X", (unsigned char) data[3]);
846 addf (str, "%.2X", (unsigned char) data[2]);
847 addf (str, "%.2X", (unsigned char) data[1]);
848 addf (str, "%.2X", (unsigned char) data[0]);
849 addf (str, "-");
850 addf (str, "%.2X", (unsigned char) data[5]);
851 addf (str, "%.2X", (unsigned char) data[4]);
852 addf (str, "-");
853 addf (str, "%.2X", (unsigned char) data[7]);
854 addf (str, "%.2X", (unsigned char) data[6]);
855 addf (str, "-");
856 addf (str, "%.2X", (unsigned char) data[8]);
857 addf (str, "%.2X", (unsigned char) data[9]);
858 addf (str, "-");
859 for (j = 10; j < 16; j++)
861 addf (str, "%.2X", (unsigned char) data[j]);
863 addf (str, "}\n");
866 static void
867 print_unique_ids (gnutls_buffer_st * str, const gnutls_x509_crt_t cert)
869 int result;
870 char buf[256]; /* if its longer, we won't bother to print it */
871 size_t buf_size = 256;
873 result = gnutls_x509_crt_get_issuer_unique_id (cert, buf, &buf_size);
874 if (result >= 0)
876 addf (str, ("\t\tIssuer 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");
884 buf_size = 256;
885 result = gnutls_x509_crt_get_subject_unique_id (cert, buf, &buf_size);
886 if (result >= 0)
888 addf (str, ("\t\tSubject Unique ID:\n"));
889 _gnutls_buffer_hexdump (str, buf, buf_size, "\t\t\t");
890 if (buf_size == 16)
891 { /* this could be a GUID */
892 guiddump (str, buf, buf_size, "\t\t\t");
897 static void
898 print_extensions (gnutls_buffer_st * str, const char *prefix, int type,
899 cert_type_t cert)
901 unsigned i, j;
902 int err;
903 int san_idx = 0;
904 int ian_idx = 0;
905 int proxy_idx = 0;
906 int basic_idx = 0;
907 int keyusage_idx = 0;
908 int keypurpose_idx = 0;
909 int ski_idx = 0;
910 int aki_idx = 0;
911 int crldist_idx = 0, pkey_usage_period_idx = 0;
912 char pfx[16];
914 for (i = 0;; i++)
916 char oid[MAX_OID_SIZE] = "";
917 size_t sizeof_oid = sizeof (oid);
918 unsigned int critical;
920 if (type == TYPE_CRT)
921 err = gnutls_x509_crt_get_extension_info (cert.crt, i,
922 oid, &sizeof_oid,
923 &critical);
925 else if (type == TYPE_CRQ)
926 err = gnutls_x509_crq_get_extension_info (cert.crq, i,
927 oid, &sizeof_oid,
928 &critical);
929 else
931 gnutls_assert ();
932 return;
935 if (err < 0)
937 if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
938 break;
939 addf (str, "error: get_extension_info: %s\n",
940 gnutls_strerror (err));
941 continue;
944 if (i == 0)
945 addf (str, _("%s\tExtensions:\n"), prefix);
947 if (strcmp (oid, "2.5.29.19") == 0)
949 if (basic_idx)
951 addf (str, "error: more than one basic constraint\n");
952 continue;
955 addf (str, _("%s\t\tBasic Constraints (%s):\n"), prefix,
956 critical ? _("critical") : _("not critical"));
958 print_basic (str, prefix, type, cert);
960 basic_idx++;
962 else if (strcmp (oid, "2.5.29.14") == 0)
964 if (ski_idx)
966 addf (str, "error: more than one SKI extension\n");
967 continue;
970 addf (str, _("%s\t\tSubject Key Identifier (%s):\n"), prefix,
971 critical ? _("critical") : _("not critical"));
973 if (type == TYPE_CRT)
974 print_ski (str, cert.crt);
976 ski_idx++;
978 else if (strcmp (oid, "2.5.29.32") == 0)
980 struct gnutls_x509_policy_st policy;
981 const char *name;
982 int x;
984 for (x = 0;; x++)
986 err =
987 gnutls_x509_crt_get_policy (cert.crt, x, &policy, &critical);
988 if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
989 break;
991 if (err < 0)
993 addf (str, "error: certificate policy: %s\n",
994 gnutls_strerror (err));
995 break;
998 if (x == 0)
999 addf (str, "%s\t\tCertificate Policies (%s):\n", prefix,
1000 critical ? _("critical") : _("not critical"));
1002 addf (str, "%s\t\t\t%s\n", prefix, policy.oid);
1003 for (j = 0; j < policy.qualifiers; j++)
1005 if (policy.qualifier[j].type == GNUTLS_X509_QUALIFIER_URI)
1006 name = "URI";
1007 else if (policy.qualifier[j].type ==
1008 GNUTLS_X509_QUALIFIER_NOTICE)
1009 name = "Note";
1010 else
1011 name = "Unknown qualifier";
1012 addf (str, "%s\t\t\t\t%s: %s\n", prefix, name,
1013 policy.qualifier[j].data);
1016 gnutls_x509_policy_release (&policy);
1019 else if (strcmp (oid, "2.5.29.35") == 0)
1022 if (aki_idx)
1024 addf (str, "error: more than one AKI extension\n");
1025 continue;
1028 addf (str, _("%s\t\tAuthority Key Identifier (%s):\n"), prefix,
1029 critical ? _("critical") : _("not critical"));
1031 if (type == TYPE_CRT)
1032 print_aki (str, TYPE_CRT, cert);
1034 aki_idx++;
1036 else if (strcmp (oid, "2.5.29.15") == 0)
1038 if (keyusage_idx)
1040 addf (str, "error: more than one key usage extension\n");
1041 continue;
1044 addf (str, _("%s\t\tKey Usage (%s):\n"), prefix,
1045 critical ? _("critical") : _("not critical"));
1047 snprintf(pfx, sizeof(pfx), "%s\t\t\t", prefix);
1048 print_key_usage (str, pfx, type, cert);
1050 keyusage_idx++;
1052 else if (strcmp (oid, "2.5.29.16") == 0)
1054 if (pkey_usage_period_idx)
1056 addf (str,
1057 "error: more than one private key usage period extension\n");
1058 continue;
1061 addf (str, _("%s\t\tPrivate Key Usage Period (%s):\n"), prefix,
1062 critical ? _("critical") : _("not critical"));
1064 print_private_key_usage_period (str, prefix, type, cert);
1066 pkey_usage_period_idx++;
1068 else if (strcmp (oid, "2.5.29.37") == 0)
1070 if (keypurpose_idx)
1072 addf (str, "error: more than one key purpose extension\n");
1073 continue;
1076 addf (str, _("%s\t\tKey Purpose (%s):\n"), prefix,
1077 critical ? _("critical") : _("not critical"));
1079 print_key_purpose (str, prefix, type, cert);
1080 keypurpose_idx++;
1082 else if (strcmp (oid, "2.5.29.17") == 0)
1084 if (san_idx)
1086 addf (str, "error: more than one SKI extension\n");
1087 continue;
1090 addf (str, _("%s\t\tSubject Alternative Name (%s):\n"), prefix,
1091 critical ? _("critical") : _("not critical"));
1093 print_altname (str, prefix, type, cert);
1095 san_idx++;
1097 else if (strcmp (oid, "2.5.29.18") == 0)
1099 if (ian_idx)
1101 addf (str, "error: more than one Issuer AltName extension\n");
1102 continue;
1105 addf (str, _("%s\t\tIssuer Alternative Name (%s):\n"), prefix,
1106 critical ? _("critical") : _("not critical"));
1108 print_altname (str, prefix, TYPE_CRT_IAN, cert);
1110 ian_idx++;
1112 else if (strcmp (oid, "2.5.29.31") == 0)
1114 if (crldist_idx)
1116 addf (str, "error: more than one CRL distribution point\n");
1117 continue;
1120 addf (str, _("%s\t\tCRL Distribution points (%s):\n"), prefix,
1121 critical ? _("critical") : _("not critical"));
1123 if (type == TYPE_CRT)
1124 print_crldist (str, cert.crt);
1125 crldist_idx++;
1127 else if (strcmp (oid, "1.3.6.1.5.5.7.1.14") == 0)
1129 if (proxy_idx)
1131 addf (str, "error: more than one proxy extension\n");
1132 continue;
1135 addf (str, _("%s\t\tProxy Certificate Information (%s):\n"), prefix,
1136 critical ? _("critical") : _("not critical"));
1138 if (type == TYPE_CRT)
1139 print_proxy (str, cert.crt);
1141 proxy_idx++;
1143 else if (strcmp (oid, "1.3.6.1.5.5.7.1.1") == 0)
1145 addf (str, _("%s\t\tAuthority Information "
1146 "Access (%s):\n"), prefix,
1147 critical ? _("critical") : _("not critical"));
1149 if (type == TYPE_CRT)
1150 print_aia (str, cert.crt);
1152 else
1154 char *buffer;
1155 size_t extlen = 0;
1157 addf (str, _("%s\t\tUnknown extension %s (%s):\n"), prefix, oid,
1158 critical ? _("critical") : _("not critical"));
1160 if (type == TYPE_CRT)
1161 err =
1162 gnutls_x509_crt_get_extension_data (cert.crt, i, NULL, &extlen);
1163 else if (type == TYPE_CRQ)
1164 err =
1165 gnutls_x509_crq_get_extension_data (cert.crq, i, NULL, &extlen);
1166 else
1168 gnutls_assert ();
1169 return;
1172 if (err < 0)
1174 addf (str, "error: get_extension_data: %s\n",
1175 gnutls_strerror (err));
1176 continue;
1179 buffer = gnutls_malloc (extlen);
1180 if (!buffer)
1182 addf (str, "error: malloc: %s\n",
1183 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
1184 continue;
1187 if (type == TYPE_CRT)
1188 err =
1189 gnutls_x509_crt_get_extension_data (cert.crt, i, buffer,
1190 &extlen);
1191 else if (type == TYPE_CRQ)
1192 err =
1193 gnutls_x509_crq_get_extension_data (cert.crq, i, buffer,
1194 &extlen);
1196 if (err < 0)
1198 gnutls_free (buffer);
1199 addf (str, "error: get_extension_data2: %s\n",
1200 gnutls_strerror (err));
1201 continue;
1204 addf (str, _("%s\t\t\tASCII: "), prefix);
1205 _gnutls_buffer_asciiprint (str, buffer, extlen);
1206 addf (str, "\n");
1208 addf (str, _("%s\t\t\tHexdump: "), prefix);
1209 _gnutls_buffer_hexprint (str, buffer, extlen);
1210 adds (str, "\n");
1212 gnutls_free (buffer);
1217 static void
1218 print_pubkey (gnutls_buffer_st * str, const char* key_name, gnutls_pubkey_t pubkey, gnutls_certificate_print_formats_t format)
1220 int err, pk;
1221 const char *name;
1222 unsigned bits;
1224 err = gnutls_pubkey_get_pk_algorithm (pubkey, &bits);
1225 if (err < 0)
1227 addf (str, "error: get_pk_algorithm: %s\n", gnutls_strerror (err));
1228 return;
1231 name = gnutls_pk_algorithm_get_name (err);
1232 if (name == NULL)
1233 name = _("unknown");
1235 pk = err;
1237 addf (str, _("\t%sPublic Key Algorithm: %s\n"), key_name, name);
1238 addf (str, _("\tAlgorithm Security Level: %s (%d bits)\n"),
1239 gnutls_sec_param_get_name (gnutls_pk_bits_to_sec_param
1240 (err, bits)), bits);
1241 switch (pk)
1243 case GNUTLS_PK_RSA:
1245 gnutls_datum_t m, e;
1247 err = gnutls_pubkey_get_pk_rsa_raw (pubkey, &m, &e);
1248 if (err < 0)
1249 addf (str, "error: get_pk_rsa_raw: %s\n", gnutls_strerror (err));
1250 else
1252 if (format == GNUTLS_CRT_PRINT_FULL_NUMBERS)
1254 addf (str, _("\t\tModulus (bits %d): "), bits);
1255 _gnutls_buffer_hexprint (str, m.data, m.size);
1256 adds (str, "\n");
1257 addf (str, _("\t\tExponent (bits %d): "), e.size * 8);
1258 _gnutls_buffer_hexprint (str, e.data, e.size);
1259 adds (str, "\n");
1261 else
1263 addf (str, _("\t\tModulus (bits %d):\n"), bits);
1264 _gnutls_buffer_hexdump (str, m.data, m.size, "\t\t\t");
1265 addf (str, _("\t\tExponent (bits %d):\n"), e.size * 8);
1266 _gnutls_buffer_hexdump (str, e.data, e.size, "\t\t\t");
1269 gnutls_free (m.data);
1270 gnutls_free (e.data);
1274 break;
1276 case GNUTLS_PK_EC:
1278 gnutls_datum_t x, y;
1279 gnutls_ecc_curve_t curve;
1281 err = gnutls_pubkey_get_pk_ecc_raw (pubkey, &curve, &x, &y);
1282 if (err < 0)
1283 addf (str, "error: get_pk_ecc_raw: %s\n", gnutls_strerror (err));
1284 else
1286 addf (str, _("\t\tCurve:\t%s\n"),
1287 gnutls_ecc_curve_get_name (curve));
1288 if (format == GNUTLS_CRT_PRINT_FULL_NUMBERS)
1290 addf (str, _("\t\tX: "));
1291 _gnutls_buffer_hexprint (str, x.data, x.size);
1292 adds (str, "\n");
1293 addf (str, _("\t\tY: "));
1294 _gnutls_buffer_hexprint (str, y.data, y.size);
1295 adds (str, "\n");
1297 else
1299 addf (str, _("\t\tX:\n"));
1300 _gnutls_buffer_hexdump (str, x.data, x.size, "\t\t\t");
1301 adds (str, _("\t\tY:\n"));
1302 _gnutls_buffer_hexdump (str, y.data, y.size, "\t\t\t");
1305 gnutls_free (x.data);
1306 gnutls_free (y.data);
1310 break;
1311 case GNUTLS_PK_DSA:
1313 gnutls_datum_t p, q, g, y;
1315 err = gnutls_pubkey_get_pk_dsa_raw (pubkey, &p, &q, &g, &y);
1316 if (err < 0)
1317 addf (str, "error: get_pk_dsa_raw: %s\n", gnutls_strerror (err));
1318 else
1320 if (format == GNUTLS_CRT_PRINT_FULL_NUMBERS)
1322 addf (str, _("\t\tPublic key (bits %d): "), bits);
1323 _gnutls_buffer_hexprint (str, y.data, y.size);
1324 adds (str, "\n");
1325 addf (str, _("\t\tP: "));
1326 _gnutls_buffer_hexprint (str, p.data, p.size);
1327 adds (str, "\n");
1328 addf (str, _("\t\tQ: "));
1329 _gnutls_buffer_hexprint (str, q.data, q.size);
1330 adds (str, "\n");
1331 addf (str, _("\t\tG: "));
1332 _gnutls_buffer_hexprint (str, g.data, g.size);
1333 adds (str, "\n");
1335 else
1337 addf (str, _("\t\tPublic key (bits %d):\n"), bits);
1338 _gnutls_buffer_hexdump (str, y.data, y.size, "\t\t\t");
1339 adds (str, _("\t\tP:\n"));
1340 _gnutls_buffer_hexdump (str, p.data, p.size, "\t\t\t");
1341 adds (str, _("\t\tQ:\n"));
1342 _gnutls_buffer_hexdump (str, q.data, q.size, "\t\t\t");
1343 adds (str, _("\t\tG:\n"));
1344 _gnutls_buffer_hexdump (str, g.data, g.size, "\t\t\t");
1347 gnutls_free (p.data);
1348 gnutls_free (q.data);
1349 gnutls_free (g.data);
1350 gnutls_free (y.data);
1354 break;
1356 default:
1357 break;
1361 static void
1362 print_crt_pubkey (gnutls_buffer_st * str, gnutls_x509_crt_t crt, gnutls_certificate_print_formats_t format)
1364 gnutls_pubkey_t pubkey;
1365 int ret;
1367 ret = gnutls_pubkey_init (&pubkey);
1368 if (ret < 0)
1369 return;
1371 ret = gnutls_pubkey_import_x509 (pubkey, crt, 0);
1372 if (ret < 0)
1373 goto cleanup;
1375 print_pubkey (str, _("Subject "), pubkey, format);
1377 cleanup:
1378 gnutls_pubkey_deinit (pubkey);
1379 return;
1382 static void
1383 print_cert (gnutls_buffer_st * str, gnutls_x509_crt_t cert,
1384 gnutls_certificate_print_formats_t format)
1386 /* Version. */
1388 int version = gnutls_x509_crt_get_version (cert);
1389 if (version < 0)
1390 addf (str, "error: get_version: %s\n", gnutls_strerror (version));
1391 else
1392 addf (str, _("\tVersion: %d\n"), version);
1395 /* Serial. */
1397 char serial[128];
1398 size_t serial_size = sizeof (serial);
1399 int err;
1401 err = gnutls_x509_crt_get_serial (cert, serial, &serial_size);
1402 if (err < 0)
1403 addf (str, "error: get_serial: %s\n", gnutls_strerror (err));
1404 else
1406 adds (str, _("\tSerial Number (hex): "));
1407 _gnutls_buffer_hexprint (str, serial, serial_size);
1408 adds (str, "\n");
1412 /* Issuer. */
1413 if (format != GNUTLS_CRT_PRINT_UNSIGNED_FULL)
1415 char *dn;
1416 size_t dn_size = 0;
1417 int err;
1419 err = gnutls_x509_crt_get_issuer_dn (cert, NULL, &dn_size);
1420 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
1421 addf (str, "error: get_issuer_dn: %s\n", gnutls_strerror (err));
1422 else
1424 dn = gnutls_malloc (dn_size);
1425 if (!dn)
1426 addf (str, "error: malloc (%d): %s\n", (int) dn_size,
1427 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
1428 else
1430 err = gnutls_x509_crt_get_issuer_dn (cert, dn, &dn_size);
1431 if (err < 0)
1432 addf (str, "error: get_issuer_dn: %s\n",
1433 gnutls_strerror (err));
1434 else
1435 addf (str, _("\tIssuer: %s\n"), dn);
1436 gnutls_free (dn);
1441 /* Validity. */
1443 time_t tim;
1445 adds (str, _("\tValidity:\n"));
1447 tim = gnutls_x509_crt_get_activation_time (cert);
1449 char s[42];
1450 size_t max = sizeof (s);
1451 struct tm t;
1453 if (gmtime_r (&tim, &t) == NULL)
1454 addf (str, "error: gmtime_r (%ld)\n", (unsigned long) tim);
1455 else if (strftime (s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0)
1456 addf (str, "error: strftime (%ld)\n", (unsigned long) tim);
1457 else
1458 addf (str, _("\t\tNot Before: %s\n"), s);
1461 tim = gnutls_x509_crt_get_expiration_time (cert);
1463 char s[42];
1464 size_t max = sizeof (s);
1465 struct tm t;
1467 if (gmtime_r (&tim, &t) == NULL)
1468 addf (str, "error: gmtime_r (%ld)\n", (unsigned long) tim);
1469 else if (strftime (s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0)
1470 addf (str, "error: strftime (%ld)\n", (unsigned long) tim);
1471 else
1472 addf (str, _("\t\tNot After: %s\n"), s);
1476 /* Subject. */
1478 char *dn;
1479 size_t dn_size = 0;
1480 int err;
1482 err = gnutls_x509_crt_get_dn (cert, NULL, &dn_size);
1483 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
1484 addf (str, "error: get_dn: %s\n", gnutls_strerror (err));
1485 else
1487 dn = gnutls_malloc (dn_size);
1488 if (!dn)
1489 addf (str, "error: malloc (%d): %s\n", (int) dn_size,
1490 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
1491 else
1493 err = gnutls_x509_crt_get_dn (cert, dn, &dn_size);
1494 if (err < 0)
1495 addf (str, "error: get_dn: %s\n", gnutls_strerror (err));
1496 else
1497 addf (str, _("\tSubject: %s\n"), dn);
1498 gnutls_free (dn);
1503 /* SubjectPublicKeyInfo. */
1504 print_crt_pubkey(str, cert, format);
1506 print_unique_ids (str, cert);
1508 /* Extensions. */
1509 if (gnutls_x509_crt_get_version (cert) >= 3)
1511 cert_type_t ccert;
1513 ccert.crt = cert;
1514 print_extensions (str, "", TYPE_CRT, ccert);
1517 /* Signature. */
1518 if (format != GNUTLS_CRT_PRINT_UNSIGNED_FULL)
1520 int err;
1521 size_t size = 0;
1522 char *buffer = NULL;
1524 err = gnutls_x509_crt_get_signature_algorithm (cert);
1525 if (err < 0)
1526 addf (str, "error: get_signature_algorithm: %s\n",
1527 gnutls_strerror (err));
1528 else
1530 const char *name = gnutls_sign_algorithm_get_name (err);
1531 if (name == NULL)
1532 name = _("unknown");
1533 addf (str, _("\tSignature Algorithm: %s\n"), name);
1535 if (gnutls_sign_is_secure (err) == 0)
1537 adds (str, _("warning: signed using a broken signature "
1538 "algorithm that can be forged.\n"));
1541 err = gnutls_x509_crt_get_signature (cert, buffer, &size);
1542 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
1544 addf (str, "error: get_signature: %s\n", gnutls_strerror (err));
1545 return;
1548 buffer = gnutls_malloc (size);
1549 if (!buffer)
1551 addf (str, "error: malloc: %s\n",
1552 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
1553 return;
1556 err = gnutls_x509_crt_get_signature (cert, buffer, &size);
1557 if (err < 0)
1559 gnutls_free (buffer);
1560 addf (str, "error: get_signature2: %s\n", gnutls_strerror (err));
1561 return;
1564 adds (str, _("\tSignature:\n"));
1565 _gnutls_buffer_hexdump (str, buffer, size, "\t\t");
1567 gnutls_free (buffer);
1571 static void
1572 print_fingerprint (gnutls_buffer_st * str, gnutls_x509_crt_t cert,
1573 gnutls_digest_algorithm_t algo)
1575 int err;
1576 char buffer[MAX_HASH_SIZE];
1577 size_t size = sizeof (buffer);
1579 err = gnutls_x509_crt_get_fingerprint (cert, algo, buffer, &size);
1580 if (err < 0)
1582 addf (str, "error: get_fingerprint: %s\n", gnutls_strerror (err));
1583 return;
1586 if (algo == GNUTLS_DIG_MD5)
1587 adds (str, _("\tMD5 fingerprint:\n\t\t"));
1588 else
1589 adds (str, _("\tSHA-1 fingerprint:\n\t\t"));
1590 _gnutls_buffer_hexprint (str, buffer, size);
1591 adds (str, "\n");
1594 static void
1595 print_keyid (gnutls_buffer_st * str, gnutls_x509_crt_t cert)
1597 int err;
1598 unsigned char buffer[32];
1599 size_t size = sizeof (buffer);
1600 const char *name;
1601 char *p;
1602 unsigned int bits;
1604 err = gnutls_x509_crt_get_key_id (cert, 0, buffer, &size);
1605 if (err < 0)
1607 addf (str, "error: get_key_id: %s\n", gnutls_strerror (err));
1608 return;
1611 adds (str, _("\tPublic Key Id:\n\t\t"));
1612 _gnutls_buffer_hexprint (str, buffer, size);
1613 adds (str, "\n");
1615 err = gnutls_x509_crt_get_pk_algorithm (cert, &bits);
1616 if (err < 0)
1617 return;
1619 name = gnutls_pk_get_name (err);
1620 if (name == NULL)
1621 return;
1623 p = _gnutls_key_fingerprint_randomart (buffer, size, name, bits, "\t\t");
1624 if (p == NULL)
1625 return;
1627 adds (str, _("\tPublic key's random art:\n"));
1628 adds (str, p);
1629 adds (str, "\n");
1631 gnutls_free (p);
1634 static void
1635 print_other (gnutls_buffer_st * str, gnutls_x509_crt_t cert,
1636 gnutls_certificate_print_formats_t format)
1638 if (format != GNUTLS_CRT_PRINT_UNSIGNED_FULL)
1640 print_fingerprint (str, cert, GNUTLS_DIG_SHA1);
1642 print_keyid (str, cert);
1645 static void
1646 print_oneline (gnutls_buffer_st * str, gnutls_x509_crt_t cert)
1648 int err;
1650 /* Subject. */
1652 char *dn;
1653 size_t dn_size = 0;
1655 err = gnutls_x509_crt_get_dn (cert, NULL, &dn_size);
1656 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
1657 addf (str, "unknown subject (%s), ", gnutls_strerror (err));
1658 else
1660 dn = gnutls_malloc (dn_size);
1661 if (!dn)
1662 addf (str, "unknown subject (%s), ",
1663 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
1664 else
1666 err = gnutls_x509_crt_get_dn (cert, dn, &dn_size);
1667 if (err < 0)
1668 addf (str, "unknown subject (%s), ", gnutls_strerror (err));
1669 else
1670 addf (str, "subject `%s', ", dn);
1671 gnutls_free (dn);
1676 /* Issuer. */
1678 char *dn;
1679 size_t dn_size = 0;
1681 err = gnutls_x509_crt_get_issuer_dn (cert, NULL, &dn_size);
1682 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
1683 addf (str, "unknown issuer (%s), ", gnutls_strerror (err));
1684 else
1686 dn = gnutls_malloc (dn_size);
1687 if (!dn)
1688 addf (str, "unknown issuer (%s), ",
1689 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
1690 else
1692 err = gnutls_x509_crt_get_issuer_dn (cert, dn, &dn_size);
1693 if (err < 0)
1694 addf (str, "unknown issuer (%s), ", gnutls_strerror (err));
1695 else
1696 addf (str, "issuer `%s', ", dn);
1697 gnutls_free (dn);
1702 /* Key algorithm and size. */
1704 unsigned int bits;
1705 const char *name = gnutls_pk_algorithm_get_name
1706 (gnutls_x509_crt_get_pk_algorithm (cert, &bits));
1707 if (name == NULL)
1708 name = "Unknown";
1709 addf (str, "%s key %d bits, ", name, bits);
1712 /* Signature Algorithm. */
1714 err = gnutls_x509_crt_get_signature_algorithm (cert);
1715 if (err < 0)
1716 addf (str, "unknown signature algorithm (%s), ", gnutls_strerror (err));
1717 else
1719 const char *name = gnutls_sign_algorithm_get_name (err);
1720 if (name == NULL)
1721 name = _("unknown");
1722 if (gnutls_sign_is_secure (err) == 0)
1723 addf (str, _("signed using %s (broken!), "), name);
1724 else
1725 addf (str, _("signed using %s, "), name);
1729 /* Validity. */
1731 time_t tim;
1733 tim = gnutls_x509_crt_get_activation_time (cert);
1735 char s[42];
1736 size_t max = sizeof (s);
1737 struct tm t;
1739 if (gmtime_r (&tim, &t) == NULL)
1740 addf (str, "unknown activation (%ld), ", (unsigned long) tim);
1741 else if (strftime (s, max, "%Y-%m-%d %H:%M:%S UTC", &t) == 0)
1742 addf (str, "failed activation (%ld), ", (unsigned long) tim);
1743 else
1744 addf (str, "activated `%s', ", s);
1747 tim = gnutls_x509_crt_get_expiration_time (cert);
1749 char s[42];
1750 size_t max = sizeof (s);
1751 struct tm t;
1753 if (gmtime_r (&tim, &t) == NULL)
1754 addf (str, "unknown expiry (%ld), ", (unsigned long) tim);
1755 else if (strftime (s, max, "%Y-%m-%d %H:%M:%S UTC", &t) == 0)
1756 addf (str, "failed expiry (%ld), ", (unsigned long) tim);
1757 else
1758 addf (str, "expires `%s', ", s);
1763 int pathlen;
1764 char *policyLanguage;
1766 err = gnutls_x509_crt_get_proxy (cert, NULL,
1767 &pathlen, &policyLanguage, NULL, NULL);
1768 if (err == 0)
1770 addf (str, "proxy certificate (policy=");
1771 if (strcmp (policyLanguage, "1.3.6.1.5.5.7.21.1") == 0)
1772 addf (str, "id-ppl-inheritALL");
1773 else if (strcmp (policyLanguage, "1.3.6.1.5.5.7.21.2") == 0)
1774 addf (str, "id-ppl-independent");
1775 else
1776 addf (str, "%s", policyLanguage);
1777 if (pathlen >= 0)
1778 addf (str, ", pathlen=%d), ", pathlen);
1779 else
1780 addf (str, "), ");
1781 gnutls_free (policyLanguage);
1786 char buffer[20];
1787 size_t size = sizeof (buffer);
1789 err = gnutls_x509_crt_get_fingerprint (cert, GNUTLS_DIG_SHA1,
1790 buffer, &size);
1791 if (err < 0)
1793 addf (str, "unknown fingerprint (%s)", gnutls_strerror (err));
1795 else
1797 addf (str, "SHA-1 fingerprint `");
1798 _gnutls_buffer_hexprint (str, buffer, size);
1799 adds (str, "'");
1806 * gnutls_x509_crt_print:
1807 * @cert: The structure to be printed
1808 * @format: Indicate the format to use
1809 * @out: Newly allocated datum with (0) terminated string.
1811 * This function will pretty print a X.509 certificate, suitable for
1812 * display to a human.
1814 * If the format is %GNUTLS_CRT_PRINT_FULL then all fields of the
1815 * certificate will be output, on multiple lines. The
1816 * %GNUTLS_CRT_PRINT_ONELINE format will generate one line with some
1817 * selected fields, which is useful for logging purposes.
1819 * The output @out needs to be deallocated using gnutls_free().
1821 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1822 * negative error value.
1825 gnutls_x509_crt_print (gnutls_x509_crt_t cert,
1826 gnutls_certificate_print_formats_t format,
1827 gnutls_datum_t * out)
1829 gnutls_buffer_st str;
1830 int ret;
1832 if (format == GNUTLS_CRT_PRINT_COMPACT)
1834 _gnutls_buffer_init (&str);
1836 print_oneline (&str, cert);
1838 _gnutls_buffer_append_data (&str, "\n", 1);
1839 print_keyid (&str, cert);
1841 _gnutls_buffer_append_data (&str, "\0", 1);
1843 ret = _gnutls_buffer_to_datum (&str, out);
1844 if (out->size > 0)
1845 out->size--;
1847 return ret;
1849 else if (format == GNUTLS_CRT_PRINT_ONELINE)
1851 _gnutls_buffer_init (&str);
1853 print_oneline (&str, cert);
1855 _gnutls_buffer_append_data (&str, "\0", 1);
1857 ret = _gnutls_buffer_to_datum (&str, out);
1858 if (out->size > 0)
1859 out->size--;
1861 return ret;
1863 else
1865 _gnutls_buffer_init (&str);
1867 _gnutls_buffer_append_str (&str, _("X.509 Certificate Information:\n"));
1869 print_cert (&str, cert, format);
1871 _gnutls_buffer_append_str (&str, _("Other Information:\n"));
1873 print_other (&str, cert, format);
1875 _gnutls_buffer_append_data (&str, "\0", 1);
1877 ret = _gnutls_buffer_to_datum (&str, out);
1878 if (out->size > 0)
1879 out->size--;
1881 return ret;
1885 static void
1886 print_crl (gnutls_buffer_st * str, gnutls_x509_crl_t crl, int notsigned)
1888 /* Version. */
1890 int version = gnutls_x509_crl_get_version (crl);
1891 if (version == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
1892 adds (str, _("\tVersion: 1 (default)\n"));
1893 else if (version < 0)
1894 addf (str, "error: get_version: %s\n", gnutls_strerror (version));
1895 else
1896 addf (str, _("\tVersion: %d\n"), version);
1899 /* Issuer. */
1900 if (!notsigned)
1902 char *dn;
1903 size_t dn_size = 0;
1904 int err;
1906 err = gnutls_x509_crl_get_issuer_dn (crl, NULL, &dn_size);
1907 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
1908 addf (str, "error: get_issuer_dn: %s\n", gnutls_strerror (err));
1909 else
1911 dn = gnutls_malloc (dn_size);
1912 if (!dn)
1913 addf (str, "error: malloc (%d): %s\n", (int) dn_size,
1914 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
1915 else
1917 err = gnutls_x509_crl_get_issuer_dn (crl, dn, &dn_size);
1918 if (err < 0)
1919 addf (str, "error: get_issuer_dn: %s\n",
1920 gnutls_strerror (err));
1921 else
1922 addf (str, _("\tIssuer: %s\n"), dn);
1924 gnutls_free (dn);
1928 /* Validity. */
1930 time_t tim;
1932 adds (str, _("\tUpdate dates:\n"));
1934 tim = gnutls_x509_crl_get_this_update (crl);
1936 char s[42];
1937 size_t max = sizeof (s);
1938 struct tm t;
1940 if (gmtime_r (&tim, &t) == NULL)
1941 addf (str, "error: gmtime_r (%ld)\n", (unsigned long) tim);
1942 else if (strftime (s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0)
1943 addf (str, "error: strftime (%ld)\n", (unsigned long) tim);
1944 else
1945 addf (str, _("\t\tIssued: %s\n"), s);
1948 tim = gnutls_x509_crl_get_next_update (crl);
1950 char s[42];
1951 size_t max = sizeof (s);
1952 struct tm t;
1954 if (tim == -1)
1955 addf (str, "\t\tNo next update time.\n");
1956 else if (gmtime_r (&tim, &t) == NULL)
1957 addf (str, "error: gmtime_r (%ld)\n", (unsigned long) tim);
1958 else if (strftime (s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0)
1959 addf (str, "error: strftime (%ld)\n", (unsigned long) tim);
1960 else
1961 addf (str, _("\t\tNext at: %s\n"), s);
1965 /* Extensions. */
1966 if (gnutls_x509_crl_get_version (crl) >= 2)
1968 size_t i;
1969 int err = 0;
1970 int aki_idx = 0;
1971 int crl_nr = 0;
1973 for (i = 0;; i++)
1975 char oid[MAX_OID_SIZE] = "";
1976 size_t sizeof_oid = sizeof (oid);
1977 unsigned int critical;
1979 err = gnutls_x509_crl_get_extension_info (crl, i,
1980 oid, &sizeof_oid,
1981 &critical);
1982 if (err < 0)
1984 if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
1985 break;
1986 addf (str, "error: get_extension_info: %s\n",
1987 gnutls_strerror (err));
1988 continue;
1991 if (i == 0)
1992 adds (str, _("\tExtensions:\n"));
1994 if (strcmp (oid, "2.5.29.20") == 0)
1996 char nr[128];
1997 size_t nr_size = sizeof (nr);
1999 if (crl_nr)
2001 addf (str, "error: more than one CRL number\n");
2002 continue;
2005 err = gnutls_x509_crl_get_number (crl, nr, &nr_size, &critical);
2007 addf (str, _("\t\tCRL Number (%s): "),
2008 critical ? _("critical") : _("not critical"));
2010 if (err < 0)
2011 addf (str, "error: get_number: %s\n", gnutls_strerror (err));
2012 else
2014 _gnutls_buffer_hexprint (str, nr, nr_size);
2015 addf (str, "\n");
2018 crl_nr++;
2020 else if (strcmp (oid, "2.5.29.35") == 0)
2022 cert_type_t ccert;
2024 if (aki_idx)
2026 addf (str, "error: more than one AKI extension\n");
2027 continue;
2030 addf (str, _("\t\tAuthority Key Identifier (%s):\n"),
2031 critical ? _("critical") : _("not critical"));
2033 ccert.crl = crl;
2034 print_aki (str, TYPE_CRL, ccert);
2036 aki_idx++;
2038 else
2040 char *buffer;
2041 size_t extlen = 0;
2043 addf (str, _("\t\tUnknown extension %s (%s):\n"), oid,
2044 critical ? _("critical") : _("not critical"));
2046 err = gnutls_x509_crl_get_extension_data (crl, i,
2047 NULL, &extlen);
2048 if (err < 0)
2050 addf (str, "error: get_extension_data: %s\n",
2051 gnutls_strerror (err));
2052 continue;
2055 buffer = gnutls_malloc (extlen);
2056 if (!buffer)
2058 addf (str, "error: malloc: %s\n",
2059 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
2060 continue;
2063 err = gnutls_x509_crl_get_extension_data (crl, i,
2064 buffer, &extlen);
2065 if (err < 0)
2067 gnutls_free (buffer);
2068 addf (str, "error: get_extension_data2: %s\n",
2069 gnutls_strerror (err));
2070 continue;
2073 adds (str, _("\t\t\tASCII: "));
2074 _gnutls_buffer_asciiprint (str, buffer, extlen);
2075 adds (str, "\n");
2077 adds (str, _("\t\t\tHexdump: "));
2078 _gnutls_buffer_hexprint (str, buffer, extlen);
2079 adds (str, "\n");
2081 gnutls_free (buffer);
2087 /* Revoked certificates. */
2089 int num = gnutls_x509_crl_get_crt_count (crl);
2090 int j;
2092 if (num)
2093 addf (str, _("\tRevoked certificates (%d):\n"), num);
2094 else
2095 adds (str, _("\tNo revoked certificates.\n"));
2097 for (j = 0; j < num; j++)
2099 unsigned char serial[128];
2100 size_t serial_size = sizeof (serial);
2101 int err;
2102 time_t tim;
2104 err = gnutls_x509_crl_get_crt_serial (crl, j, serial,
2105 &serial_size, &tim);
2106 if (err < 0)
2107 addf (str, "error: get_crt_serial: %s\n", gnutls_strerror (err));
2108 else
2110 char s[42];
2111 size_t max = sizeof (s);
2112 struct tm t;
2114 adds (str, _("\t\tSerial Number (hex): "));
2115 _gnutls_buffer_hexprint (str, serial, serial_size);
2116 adds (str, "\n");
2118 if (gmtime_r (&tim, &t) == NULL)
2119 addf (str, "error: gmtime_r (%ld)\n", (unsigned long) tim);
2120 else if (strftime (s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0)
2121 addf (str, "error: strftime (%ld)\n", (unsigned long) tim);
2122 else
2123 addf (str, _("\t\tRevoked at: %s\n"), s);
2128 /* Signature. */
2129 if (!notsigned)
2131 int err;
2132 size_t size = 0;
2133 char *buffer = NULL;
2135 err = gnutls_x509_crl_get_signature_algorithm (crl);
2136 if (err < 0)
2137 addf (str, "error: get_signature_algorithm: %s\n",
2138 gnutls_strerror (err));
2139 else
2141 const char *name = gnutls_sign_algorithm_get_name (err);
2142 if (name == NULL)
2143 name = _("unknown");
2144 addf (str, _("\tSignature Algorithm: %s\n"), name);
2146 if (gnutls_sign_is_secure (err) == 0)
2148 adds (str, _("warning: signed using a broken signature "
2149 "algorithm that can be forged.\n"));
2152 err = gnutls_x509_crl_get_signature (crl, buffer, &size);
2153 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
2155 addf (str, "error: get_signature: %s\n", gnutls_strerror (err));
2156 return;
2159 buffer = gnutls_malloc (size);
2160 if (!buffer)
2162 addf (str, "error: malloc: %s\n",
2163 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
2164 return;
2167 err = gnutls_x509_crl_get_signature (crl, buffer, &size);
2168 if (err < 0)
2170 gnutls_free (buffer);
2171 addf (str, "error: get_signature2: %s\n", gnutls_strerror (err));
2172 return;
2175 adds (str, _("\tSignature:\n"));
2176 _gnutls_buffer_hexdump (str, buffer, size, "\t\t");
2178 gnutls_free (buffer);
2183 * gnutls_x509_crl_print:
2184 * @crl: The structure to be printed
2185 * @format: Indicate the format to use
2186 * @out: Newly allocated datum with (0) terminated string.
2188 * This function will pretty print a X.509 certificate revocation
2189 * list, suitable for display to a human.
2191 * The output @out needs to be deallocated using gnutls_free().
2193 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2194 * negative error value.
2197 gnutls_x509_crl_print (gnutls_x509_crl_t crl,
2198 gnutls_certificate_print_formats_t format,
2199 gnutls_datum_t * out)
2201 gnutls_buffer_st str;
2202 int ret;
2204 _gnutls_buffer_init (&str);
2206 _gnutls_buffer_append_str
2207 (&str, _("X.509 Certificate Revocation List Information:\n"));
2209 print_crl (&str, crl, format == GNUTLS_CRT_PRINT_UNSIGNED_FULL);
2211 _gnutls_buffer_append_data (&str, "\0", 1);
2213 ret = _gnutls_buffer_to_datum (&str, out);
2214 if (out->size > 0)
2215 out->size--;
2217 return ret;
2220 static void
2221 print_crq_pubkey (gnutls_buffer_st * str, gnutls_x509_crq_t crq, gnutls_certificate_print_formats_t format)
2223 gnutls_pubkey_t pubkey;
2224 int ret;
2226 ret = gnutls_pubkey_init (&pubkey);
2227 if (ret < 0)
2228 return;
2230 ret = gnutls_pubkey_import_x509_crq (pubkey, crq, 0);
2231 if (ret < 0)
2232 goto cleanup;
2234 print_pubkey (str, _("Subject "), pubkey, format);
2236 cleanup:
2237 gnutls_pubkey_deinit (pubkey);
2238 return;
2241 static void
2242 print_crq (gnutls_buffer_st * str, gnutls_x509_crq_t cert, gnutls_certificate_print_formats_t format)
2244 /* Version. */
2246 int version = gnutls_x509_crq_get_version (cert);
2247 if (version < 0)
2248 addf (str, "error: get_version: %s\n", gnutls_strerror (version));
2249 else
2250 addf (str, _("\tVersion: %d\n"), version);
2253 /* Subject */
2255 char *dn;
2256 size_t dn_size = 0;
2257 int err;
2259 err = gnutls_x509_crq_get_dn (cert, NULL, &dn_size);
2260 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
2261 addf (str, "error: get_dn: %s\n", gnutls_strerror (err));
2262 else
2264 dn = gnutls_malloc (dn_size);
2265 if (!dn)
2266 addf (str, "error: malloc (%d): %s\n", (int) dn_size,
2267 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
2268 else
2270 err = gnutls_x509_crq_get_dn (cert, dn, &dn_size);
2271 if (err < 0)
2272 addf (str, "error: get_dn: %s\n", gnutls_strerror (err));
2273 else
2274 addf (str, _("\tSubject: %s\n"), dn);
2275 gnutls_free (dn);
2280 /* SubjectPublicKeyInfo. */
2282 int err;
2283 unsigned int bits;
2285 err = gnutls_x509_crq_get_pk_algorithm (cert, &bits);
2286 if (err < 0)
2287 addf (str, "error: get_pk_algorithm: %s\n", gnutls_strerror (err));
2288 else
2289 print_crq_pubkey (str, cert, format);
2292 /* parse attributes */
2294 size_t i;
2295 int err = 0;
2296 int extensions = 0;
2297 int challenge = 0;
2299 for (i = 0;; i++)
2301 char oid[MAX_OID_SIZE] = "";
2302 size_t sizeof_oid = sizeof (oid);
2304 err = gnutls_x509_crq_get_attribute_info (cert, i, oid, &sizeof_oid);
2305 if (err < 0)
2307 if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
2308 break;
2309 addf (str, "error: get_extension_info: %s\n",
2310 gnutls_strerror (err));
2311 continue;
2314 if (i == 0)
2315 adds (str, _("\tAttributes:\n"));
2317 if (strcmp (oid, "1.2.840.113549.1.9.14") == 0)
2319 cert_type_t ccert;
2321 if (extensions)
2323 addf (str, "error: more than one extensionsRequest\n");
2324 continue;
2327 ccert.crq = cert;
2328 print_extensions (str, "\t", TYPE_CRQ, ccert);
2330 extensions++;
2332 else if (strcmp (oid, "1.2.840.113549.1.9.7") == 0)
2334 char *pass;
2335 size_t size;
2337 if (challenge)
2339 adds (str,
2340 "error: more than one Challenge password attribute\n");
2341 continue;
2344 err = gnutls_x509_crq_get_challenge_password (cert, NULL, &size);
2345 if (err < 0)
2347 addf (str, "error: get_challenge_password: %s\n",
2348 gnutls_strerror (err));
2349 continue;
2352 size++;
2354 pass = gnutls_malloc (size);
2355 if (!pass)
2357 addf (str, "error: malloc: %s\n",
2358 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
2359 continue;
2362 err = gnutls_x509_crq_get_challenge_password (cert, pass, &size);
2363 if (err < 0)
2364 addf (str, "error: get_challenge_password: %s\n",
2365 gnutls_strerror (err));
2366 else
2367 addf (str, _("\t\tChallenge password: %s\n"), pass);
2369 gnutls_free (pass);
2371 challenge++;
2373 else
2375 char *buffer;
2376 size_t extlen = 0;
2378 addf (str, _("\t\tUnknown attribute %s:\n"), oid);
2380 err = gnutls_x509_crq_get_attribute_data (cert, i, NULL, &extlen);
2381 if (err < 0)
2383 addf (str, "error: get_attribute_data: %s\n",
2384 gnutls_strerror (err));
2385 continue;
2388 buffer = gnutls_malloc (extlen);
2389 if (!buffer)
2391 addf (str, "error: malloc: %s\n",
2392 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
2393 continue;
2396 err = gnutls_x509_crq_get_attribute_data (cert, i,
2397 buffer, &extlen);
2398 if (err < 0)
2400 gnutls_free (buffer);
2401 addf (str, "error: get_attribute_data2: %s\n",
2402 gnutls_strerror (err));
2403 continue;
2406 adds (str, _("\t\t\tASCII: "));
2407 _gnutls_buffer_asciiprint (str, buffer, extlen);
2408 adds (str, "\n");
2410 adds (str, _("\t\t\tHexdump: "));
2411 _gnutls_buffer_hexprint (str, buffer, extlen);
2412 adds (str, "\n");
2414 gnutls_free (buffer);
2420 static void
2421 print_crq_other (gnutls_buffer_st * str, gnutls_x509_crq_t crq)
2423 int err;
2424 size_t size = 0;
2425 unsigned char *buffer = NULL;
2427 err = gnutls_x509_crq_get_key_id (crq, 0, buffer, &size);
2428 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
2430 addf (str, "error: get_key_id: %s\n", gnutls_strerror (err));
2431 return;
2434 buffer = gnutls_malloc (size);
2435 if (!buffer)
2437 addf (str, "error: malloc: %s\n",
2438 gnutls_strerror (GNUTLS_E_MEMORY_ERROR));
2439 return;
2442 err = gnutls_x509_crq_get_key_id (crq, 0, buffer, &size);
2443 if (err < 0)
2445 gnutls_free (buffer);
2446 addf (str, "error: get_key_id2: %s\n", gnutls_strerror (err));
2447 return;
2450 adds (str, _("\tPublic Key Id:\n\t\t"));
2451 _gnutls_buffer_hexprint (str, buffer, size);
2452 adds (str, "\n");
2454 gnutls_free (buffer);
2458 * gnutls_x509_crq_print:
2459 * @crq: The structure to be printed
2460 * @format: Indicate the format to use
2461 * @out: Newly allocated datum with (0) terminated string.
2463 * This function will pretty print a certificate request, suitable for
2464 * display to a human.
2466 * The output @out needs to be deallocated using gnutls_free().
2468 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2469 * negative error value.
2471 * Since: 2.8.0
2474 gnutls_x509_crq_print (gnutls_x509_crq_t crq,
2475 gnutls_certificate_print_formats_t format,
2476 gnutls_datum_t * out)
2478 gnutls_buffer_st str;
2479 int ret;
2481 _gnutls_buffer_init (&str);
2483 _gnutls_buffer_append_str
2484 (&str, _("PKCS #10 Certificate Request Information:\n"));
2486 print_crq (&str, crq, format);
2488 _gnutls_buffer_append_str (&str, _("Other Information:\n"));
2490 print_crq_other (&str, crq);
2492 _gnutls_buffer_append_data (&str, "\0", 1);
2494 ret = _gnutls_buffer_to_datum (&str, out);
2495 if (out->size > 0)
2496 out->size--;
2498 return ret;
2501 static void
2502 print_pubkey_other (gnutls_buffer_st * str, gnutls_pubkey_t pubkey, gnutls_certificate_print_formats_t format)
2504 uint8_t buffer[MAX_HASH_SIZE];
2505 size_t size = sizeof(buffer);
2506 int ret;
2507 unsigned int usage;
2508 cert_type_t ccert;
2510 ccert.pubkey = pubkey;
2512 ret = gnutls_pubkey_get_key_usage (pubkey, &usage);
2513 if (ret < 0)
2515 addf (str, "error: get_key_usage: %s\n", gnutls_strerror (ret));
2516 return;
2519 adds (str, "\n");
2520 adds (str, _("Public Key Usage:\n"));
2521 print_key_usage (str, "\t", TYPE_PUBKEY, ccert);
2523 ret = gnutls_pubkey_get_key_id (pubkey, 0, buffer, &size);
2524 if (ret < 0)
2526 addf (str, "error: get_key_id: %s\n", gnutls_strerror (ret));
2527 return;
2530 adds (str, "\n");
2531 adds (str, _("Public Key ID: "));
2532 _gnutls_buffer_hexprint (str, buffer, size);
2533 adds (str, "\n");
2537 * gnutls_pubkey_print:
2538 * @pubkey: The structure to be printed
2539 * @format: Indicate the format to use
2540 * @out: Newly allocated datum with (0) terminated string.
2542 * This function will pretty print public key information, suitable for
2543 * display to a human.
2545 * Only %GNUTLS_CRT_PRINT_FULL and %GNUTLS_CRT_PRINT_FULL_NUMBERS
2546 * are implemented.
2548 * The output @out needs to be deallocated using gnutls_free().
2550 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2551 * negative error value.
2553 * Since: 3.1.5
2556 gnutls_pubkey_print (gnutls_pubkey_t pubkey,
2557 gnutls_certificate_print_formats_t format,
2558 gnutls_datum_t * out)
2560 gnutls_buffer_st str;
2561 int ret;
2563 _gnutls_buffer_init (&str);
2565 _gnutls_buffer_append_str (&str, _("Public Key Information:\n"));
2567 print_pubkey (&str, "", pubkey, format);
2568 print_pubkey_other (&str, pubkey, format);
2570 _gnutls_buffer_append_data (&str, "\0", 1);
2572 ret = _gnutls_buffer_to_datum (&str, out);
2573 if (out->size > 0)
2574 out->size--;
2576 return ret;