Imported Upstream version 3.0.21
[platform/upstream/gnutls.git] / src / common.c
1 /*
2  * Copyright (C) 2000-2012 Free Software Foundation, Inc.
3  * Author: Nikos Mavrogiannopoulos
4  *
5  * This file is part of GnuTLS.
6  *
7  * GnuTLS is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * GnuTLS is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <config.h>
22
23 /* Work around problem reported in
24    <http://permalink.gmane.org/gmane.comp.lib.gnulib.bugs/15755>.*/
25 #if GETTIMEOFDAY_CLOBBERS_LOCALTIME
26 #undef localtime
27 #endif
28
29 #include <getpass.h>
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <gnutls/gnutls.h>
35 #include <gnutls/x509.h>
36 #include <gnutls/openpgp.h>
37 #include <time.h>
38 #include <common.h>
39
40 #define SU(x) (x!=NULL?x:"Unknown")
41
42 extern int verbose;
43
44 const char str_unknown[] = "(unknown)";
45
46 /* Hex encodes the given data.
47  */
48 const char *
49 raw_to_string (const unsigned char *raw, size_t raw_size)
50 {
51     static char buf[1024];
52     size_t i;
53     if (raw_size == 0)
54         return "(empty)";
55
56     if (raw_size * 3 + 1 >= sizeof (buf))
57         return "(too large)";
58
59     for (i = 0; i < raw_size; i++)
60       {
61           sprintf (&(buf[i * 3]), "%02X%s", raw[i],
62                    (i == raw_size - 1) ? "" : ":");
63       }
64     buf[sizeof (buf) - 1] = '\0';
65
66     return buf;
67 }
68
69 static void
70 print_x509_info_compact (gnutls_session_t session)
71 {
72     gnutls_x509_crt_t crt;
73     const gnutls_datum_t *cert_list;
74     unsigned int cert_list_size = 0;
75     int ret;
76     gnutls_datum_t cinfo;
77
78     cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
79     if (cert_list_size == 0)
80       {
81           fprintf (stderr, "No certificates found!\n");
82           return;
83       }
84
85     gnutls_x509_crt_init (&crt);
86     ret =
87           gnutls_x509_crt_import (crt, &cert_list[0],
88                                   GNUTLS_X509_FMT_DER);
89     if (ret < 0)
90       {
91         fprintf (stderr, "Decoding error: %s\n",
92                  gnutls_strerror (ret));
93         return;
94       }
95
96     ret =
97       gnutls_x509_crt_print (crt, GNUTLS_CRT_PRINT_COMPACT, &cinfo);
98     if (ret == 0)
99       {
100         printf ("- X.509 cert: %s\n", cinfo.data);
101         gnutls_free (cinfo.data);
102       }
103
104     gnutls_x509_crt_deinit (crt);
105 }
106
107 static void
108 print_x509_info (gnutls_session_t session, int flag, int print_cert)
109 {
110     gnutls_x509_crt_t crt;
111     const gnutls_datum_t *cert_list;
112     unsigned int cert_list_size = 0, j;
113     int ret;
114     
115     cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
116     if (cert_list_size == 0)
117       {
118           fprintf (stderr, "No certificates found!\n");
119           return;
120       }
121
122     printf ("- Certificate type: X.509\n");
123     printf ("- Got a certificate list of %d certificates.\n",
124             cert_list_size);
125
126     for (j = 0; j < cert_list_size; j++)
127       {
128           gnutls_datum_t cinfo;
129
130           gnutls_x509_crt_init (&crt);
131           ret =
132               gnutls_x509_crt_import (crt, &cert_list[j],
133                                       GNUTLS_X509_FMT_DER);
134           if (ret < 0)
135             {
136                 fprintf (stderr, "Decoding error: %s\n",
137                          gnutls_strerror (ret));
138                 return;
139             }
140
141           printf ("- Certificate[%d] info:\n - ", j);
142           if (flag == GNUTLS_CRT_PRINT_COMPACT && j > 0) flag = GNUTLS_CRT_PRINT_ONELINE;
143
144           ret =
145             gnutls_x509_crt_print (crt, flag, &cinfo);
146           if (ret == 0)
147             {
148                 printf ("%s\n", cinfo.data);
149                 gnutls_free (cinfo.data);
150             }
151
152           if (print_cert)
153             {
154                 size_t size = 0;
155                 char *p = NULL;
156
157                 ret =
158                     gnutls_x509_crt_export (crt, GNUTLS_X509_FMT_PEM, p,
159                                             &size);
160                 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
161                   {
162                       p = malloc (size);
163                       if (!p)
164                         {
165                             fprintf (stderr, "gnutls_malloc\n");
166                             exit (1);
167                         }
168
169                       ret =
170                           gnutls_x509_crt_export (crt, GNUTLS_X509_FMT_PEM,
171                                                   p, &size);
172                   }
173                 if (ret < 0)
174                   {
175                       fprintf (stderr, "Encoding error: %s\n",
176                                gnutls_strerror (ret));
177                       return;
178                   }
179
180                 fputs ("\n", stdout);
181                 fputs (p, stdout);
182                 fputs ("\n", stdout);
183
184                 gnutls_free (p);
185             }
186
187           gnutls_x509_crt_deinit (crt);
188       }
189 }
190
191 /* returns true or false, depending on whether the hostname
192  * matches to certificate */
193 static int
194 verify_x509_hostname (gnutls_session_t session, const char *hostname)
195 {
196   gnutls_x509_crt_t crt;
197   const gnutls_datum_t *cert_list;
198   unsigned int cert_list_size = 0;
199   int ret;
200
201   cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
202   if (cert_list_size == 0)
203     {
204       fprintf (stderr, "No certificates found!\n");
205       return 0;
206     }
207
208   gnutls_x509_crt_init (&crt);
209   ret =
210       gnutls_x509_crt_import (crt, &cert_list[0],
211                               GNUTLS_X509_FMT_DER);
212   if (ret < 0)
213     {
214       fprintf (stderr, "Decoding error: %s\n",
215                gnutls_strerror (ret));
216       return 0;
217     }
218
219   /* Check the hostname of the first certificate if it matches
220    * the name of the host we connected to.
221    */
222   if (hostname != NULL)
223     {
224       if (gnutls_x509_crt_check_hostname (crt, hostname) == 0)
225         {
226           printf
227              ("- The hostname in the certificate does NOT match '%s'\n",
228               hostname);
229           ret = 0;
230         }
231       else
232         {
233           printf ("- The hostname in the certificate matches '%s'.\n",
234                   hostname);
235           ret = 1;
236         }
237     }
238
239   gnutls_x509_crt_deinit (crt);
240
241   return ret;
242 }
243
244 #ifdef ENABLE_OPENPGP
245 /* returns true or false, depending on whether the hostname
246  * matches to certificate */
247 static int
248 verify_openpgp_hostname (gnutls_session_t session, const char *hostname)
249 {
250   gnutls_openpgp_crt_t crt;
251   const gnutls_datum_t *cert_list;
252   unsigned int cert_list_size = 0;
253   int ret;
254
255   cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
256   if (cert_list_size == 0)
257     {
258       fprintf (stderr, "No certificates found!\n");
259       return 0;
260     }
261
262   gnutls_openpgp_crt_init (&crt);
263   ret =
264       gnutls_openpgp_crt_import (crt, &cert_list[0],
265                               GNUTLS_OPENPGP_FMT_RAW);
266   if (ret < 0)
267     {
268       fprintf (stderr, "Decoding error: %s\n",
269                gnutls_strerror (ret));
270       return 0;
271     }
272
273   /* Check the hostname of the first certificate if it matches
274    * the name of the host we connected to.
275    */
276   if (gnutls_openpgp_crt_check_hostname (crt, hostname) == 0)
277     {
278       printf
279              ("- The hostname in the certificate does NOT match '%s'\n",
280               hostname);
281       ret = 0;
282     }
283   else
284     {
285       printf ("- The hostname in the certificate matches '%s'.\n",
286               hostname);
287       ret = 1;
288     }
289
290   gnutls_openpgp_crt_deinit (crt);
291
292   return ret;
293 }
294
295 static void
296 print_openpgp_info_compact (gnutls_session_t session)
297 {
298
299     gnutls_openpgp_crt_t crt;
300     const gnutls_datum_t *cert_list;
301     unsigned int cert_list_size = 0;
302     int ret;
303
304     cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
305
306     if (cert_list_size > 0)
307       {
308           gnutls_datum_t cinfo;
309
310           gnutls_openpgp_crt_init (&crt);
311           ret = gnutls_openpgp_crt_import (crt, &cert_list[0],
312                                            GNUTLS_OPENPGP_FMT_RAW);
313           if (ret < 0)
314             {
315                 fprintf (stderr, "Decoding error: %s\n",
316                          gnutls_strerror (ret));
317                 return;
318             }
319
320           ret =
321               gnutls_openpgp_crt_print (crt, GNUTLS_CRT_PRINT_COMPACT, &cinfo);
322           if (ret == 0)
323             {
324                 printf ("- OpenPGP cert: %s\n", cinfo.data);
325                 gnutls_free (cinfo.data);
326             }
327
328           gnutls_openpgp_crt_deinit (crt);
329       }
330 }
331
332 static void
333 print_openpgp_info (gnutls_session_t session, int flag, int print_cert)
334 {
335
336     gnutls_openpgp_crt_t crt;
337     const gnutls_datum_t *cert_list;
338     unsigned int cert_list_size = 0;
339     int ret;
340
341     printf ("- Certificate type: OpenPGP\n");
342
343     cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
344
345     if (cert_list_size > 0)
346       {
347           gnutls_datum_t cinfo;
348
349           gnutls_openpgp_crt_init (&crt);
350           ret = gnutls_openpgp_crt_import (crt, &cert_list[0],
351                                            GNUTLS_OPENPGP_FMT_RAW);
352           if (ret < 0)
353             {
354                 fprintf (stderr, "Decoding error: %s\n",
355                          gnutls_strerror (ret));
356                 return;
357             }
358
359           ret =
360               gnutls_openpgp_crt_print (crt, flag, &cinfo);
361           if (ret == 0)
362             {
363                 printf ("- %s\n", cinfo.data);
364                 gnutls_free (cinfo.data);
365             }
366
367           if (print_cert)
368             {
369                 size_t size = 0;
370                 char *p = NULL;
371
372                 ret =
373                     gnutls_openpgp_crt_export (crt,
374                                                GNUTLS_OPENPGP_FMT_BASE64,
375                                                p, &size);
376                 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
377                   {
378                       p = malloc (size);
379                       if (!p)
380                         {
381                             fprintf (stderr, "gnutls_malloc\n");
382                             exit (1);
383                         }
384
385                       ret =
386                           gnutls_openpgp_crt_export (crt,
387                                                      GNUTLS_OPENPGP_FMT_BASE64,
388                                                      p, &size);
389                   }
390                 if (ret < 0)
391                   {
392                       fprintf (stderr, "Encoding error: %s\n",
393                                gnutls_strerror (ret));
394                       return;
395                   }
396
397                 fputs (p, stdout);
398                 fputs ("\n", stdout);
399
400                 gnutls_free (p);
401             }
402
403           gnutls_openpgp_crt_deinit (crt);
404       }
405 }
406
407 #endif
408
409 /* returns false (0) if not verified, or true (1) otherwise 
410  */
411 int
412 cert_verify (gnutls_session_t session, const char* hostname)
413 {
414     int rc;
415     unsigned int status = 0;
416     int type;
417
418     rc = gnutls_certificate_verify_peers2 (session, &status);
419     if (rc == GNUTLS_E_NO_CERTIFICATE_FOUND)
420       {
421           printf ("- Peer did not send any certificate.\n");
422           return 0;
423       }
424
425     if (rc < 0)
426       {
427           printf ("- Could not verify certificate (err: %s)\n",
428                   gnutls_strerror (rc));
429           return 0;
430       }
431
432     type = gnutls_certificate_type_get (session);
433     if (type == GNUTLS_CRT_X509)
434       {
435
436           if (status & GNUTLS_CERT_REVOKED)
437               printf ("- Peer's certificate chain revoked\n");
438           if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
439               printf ("- Peer's certificate issuer is unknown\n");
440           if (status & GNUTLS_CERT_SIGNER_NOT_CA)
441               printf ("- Peer's certificate issuer is not a CA\n");
442           if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
443               printf
444                   ("- Peer's certificate chain uses insecure algorithm\n");
445           if (status & GNUTLS_CERT_NOT_ACTIVATED)
446               printf
447                   ("- Peer's certificate chain uses not yet valid certificate\n");
448           if (status & GNUTLS_CERT_EXPIRED)
449               printf
450                   ("- Peer's certificate chain uses expired certificate\n");
451           if (status & GNUTLS_CERT_INVALID)
452               printf ("- Peer's certificate is NOT trusted\n");
453           else
454               printf ("- Peer's certificate is trusted\n");
455
456           rc = verify_x509_hostname (session, hostname);
457           if (rc == 0) status |= GNUTLS_CERT_INVALID;
458       }
459     else if (type == GNUTLS_CRT_OPENPGP)
460       {
461           if (status & GNUTLS_CERT_INVALID)
462               printf ("- Peer's key is invalid\n");
463           else
464               printf ("- Peer's key is valid\n");
465           if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
466               printf ("- Could not find a signer of the peer's key\n");
467
468           rc = verify_openpgp_hostname (session, hostname);
469           if (rc == 0) status |= GNUTLS_CERT_INVALID;
470       }
471     else
472       {
473         fprintf(stderr, "Unknown certificate type\n");
474         status |= GNUTLS_CERT_INVALID;
475       }
476
477     if (status)
478       return 0;
479
480     return 1;
481 }
482
483 static void
484 print_dh_info (gnutls_session_t session, const char *str, int print)
485 {
486     printf ("- %sDiffie-Hellman parameters\n", str);
487     printf (" - Using prime: %d bits\n",
488             gnutls_dh_get_prime_bits (session));
489     printf (" - Secret key: %d bits\n",
490             gnutls_dh_get_secret_bits (session));
491     printf (" - Peer's public key: %d bits\n",
492             gnutls_dh_get_peers_public_bits (session));
493
494     if (print)
495       {
496           int ret;
497           gnutls_datum_t raw_gen = { NULL, 0 };
498           gnutls_datum_t raw_prime = { NULL, 0 };
499           gnutls_dh_params_t dh_params = NULL;
500           unsigned char *params_data = NULL;
501           size_t params_data_size = 0;
502
503           ret = gnutls_dh_get_group (session, &raw_gen, &raw_prime);
504           if (ret)
505             {
506                 fprintf (stderr, "gnutls_dh_get_group %d\n", ret);
507                 goto out;
508             }
509
510           ret = gnutls_dh_params_init (&dh_params);
511           if (ret)
512             {
513                 fprintf (stderr, "gnutls_dh_params_init %d\n", ret);
514                 goto out;
515             }
516
517           ret =
518               gnutls_dh_params_import_raw (dh_params, &raw_prime,
519                                            &raw_gen);
520           if (ret)
521             {
522                 fprintf (stderr, "gnutls_dh_params_import_raw %d\n", ret);
523                 goto out;
524             }
525
526           ret = gnutls_dh_params_export_pkcs3 (dh_params,
527                                                GNUTLS_X509_FMT_PEM,
528                                                params_data,
529                                                &params_data_size);
530           if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
531             {
532                 fprintf (stderr, "gnutls_dh_params_export_pkcs3 %d\n",
533                          ret);
534                 goto out;
535             }
536
537           params_data = gnutls_malloc (params_data_size);
538           if (!params_data)
539             {
540                 fprintf (stderr, "gnutls_malloc %d\n", ret);
541                 goto out;
542             }
543
544           ret = gnutls_dh_params_export_pkcs3 (dh_params,
545                                                GNUTLS_X509_FMT_PEM,
546                                                params_data,
547                                                &params_data_size);
548           if (ret)
549             {
550                 fprintf (stderr, "gnutls_dh_params_export_pkcs3-2 %d\n",
551                          ret);
552                 goto out;
553             }
554
555           printf (" - PKCS#3 format:\n\n%.*s\n", (int) params_data_size,
556                   params_data);
557
558         out:
559           gnutls_free (params_data);
560           gnutls_free (raw_prime.data);
561           gnutls_free (raw_gen.data);
562           gnutls_dh_params_deinit (dh_params);
563       }
564 }
565
566 static void
567 print_ecdh_info (gnutls_session_t session, const char *str)
568 {
569     int curve;
570
571     printf ("- %sEC Diffie-Hellman parameters\n", str);
572
573     curve = gnutls_ecc_curve_get (session);
574
575     printf (" - Using curve: %s\n", gnutls_ecc_curve_get_name (curve));
576     printf (" - Curve size: %d bits\n",
577             gnutls_ecc_curve_get_size (curve) * 8);
578
579 }
580
581 int
582 print_info (gnutls_session_t session, int print_cert)
583 {
584     const char *tmp;
585     gnutls_credentials_type_t cred;
586     gnutls_kx_algorithm_t kx;
587     unsigned char session_id[33];
588     size_t session_id_size = sizeof (session_id);
589
590     /* print session ID */
591     gnutls_session_get_id (session, session_id, &session_id_size);
592     printf ("- Session ID: %s\n",
593             raw_to_string (session_id, session_id_size));
594
595     /* print the key exchange's algorithm name
596      */
597     kx = gnutls_kx_get (session);
598
599     cred = gnutls_auth_get_type (session);
600     switch (cred)
601       {
602 #ifdef ENABLE_ANON
603       case GNUTLS_CRD_ANON:
604           if (kx == GNUTLS_KX_ANON_ECDH)
605               print_ecdh_info (session, "Anonymous ");
606           else
607               print_dh_info (session, "Anonymous ", verbose);
608           break;
609 #endif
610 #ifdef ENABLE_SRP
611       case GNUTLS_CRD_SRP:
612           /* This should be only called in server
613            * side.
614            */
615           if (gnutls_srp_server_get_username (session) != NULL)
616               printf ("- SRP authentication. Connected as '%s'\n",
617                       gnutls_srp_server_get_username (session));
618           break;
619 #endif
620 #ifdef ENABLE_PSK
621       case GNUTLS_CRD_PSK:
622           /* This returns NULL in server side.
623            */
624           if (gnutls_psk_client_get_hint (session) != NULL)
625               printf ("- PSK authentication. PSK hint '%s'\n",
626                       gnutls_psk_client_get_hint (session));
627           /* This returns NULL in client side.
628            */
629           if (gnutls_psk_server_get_username (session) != NULL)
630               printf ("- PSK authentication. Connected as '%s'\n",
631                       gnutls_psk_server_get_username (session));
632           if (kx == GNUTLS_KX_DHE_PSK)
633               print_dh_info (session, "Ephemeral ", verbose);
634           if (kx == GNUTLS_KX_ECDHE_PSK)
635               print_ecdh_info (session, "Ephemeral ");
636           break;
637 #endif
638       case GNUTLS_CRD_IA:
639           printf ("- TLS/IA authentication\n");
640           break;
641       case GNUTLS_CRD_CERTIFICATE:
642           {
643               char dns[256];
644               size_t dns_size = sizeof (dns);
645               unsigned int type;
646
647               /* This fails in client side */
648               if (gnutls_server_name_get
649                   (session, dns, &dns_size, &type, 0) == 0)
650                 {
651                     printf ("- Given server name[%d]: %s\n", type, dns);
652                 }
653           }
654
655           print_cert_info (session, verbose, print_cert);
656
657           if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS)
658               print_dh_info (session, "Ephemeral ", verbose);
659           else if (kx == GNUTLS_KX_ECDHE_RSA
660                    || kx == GNUTLS_KX_ECDHE_ECDSA)
661               print_ecdh_info (session, "Ephemeral ");
662       }
663
664     tmp =
665         SU (gnutls_protocol_get_name
666             (gnutls_protocol_get_version (session)));
667     printf ("- Version: %s\n", tmp);
668
669     tmp = SU (gnutls_kx_get_name (kx));
670     printf ("- Key Exchange: %s\n", tmp);
671
672     tmp = SU (gnutls_cipher_get_name (gnutls_cipher_get (session)));
673     printf ("- Cipher: %s\n", tmp);
674
675     tmp = SU (gnutls_mac_get_name (gnutls_mac_get (session)));
676     printf ("- MAC: %s\n", tmp);
677
678     tmp =
679         SU (gnutls_compression_get_name
680             (gnutls_compression_get (session)));
681     printf ("- Compression: %s\n", tmp);
682
683     if (verbose)
684       {
685           gnutls_datum_t cb;
686           int rc;
687
688           rc = gnutls_session_channel_binding (session,
689                                                GNUTLS_CB_TLS_UNIQUE, &cb);
690           if (rc)
691               fprintf (stderr, "Channel binding error: %s\n",
692                        gnutls_strerror (rc));
693           else
694             {
695                 size_t i;
696
697                 printf ("- Channel binding 'tls-unique': ");
698                 for (i = 0; i < cb.size; i++)
699                     printf ("%02x", cb.data[i]);
700                 printf ("\n");
701             }
702       }
703
704     /* Warning: Do not print anything more here. The 'Compression:'
705        output MUST be the last non-verbose output.  This is used by
706        Emacs starttls.el code. */
707
708     fflush (stdout);
709
710     return 0;
711 }
712
713 void
714 print_cert_info (gnutls_session_t session, int verbose, int print_cert)
715 {
716 int flag;
717
718     if (verbose) flag = GNUTLS_CRT_PRINT_FULL;
719     else flag = GNUTLS_CRT_PRINT_COMPACT;
720
721     if (gnutls_certificate_client_get_request_status (session) != 0)
722         printf ("- Server has requested a certificate.\n");
723
724     switch (gnutls_certificate_type_get (session))
725       {
726       case GNUTLS_CRT_X509:
727           print_x509_info (session, flag, print_cert);
728           break;
729 #ifdef ENABLE_OPENPGP
730       case GNUTLS_CRT_OPENPGP:
731           print_openpgp_info (session, flag, print_cert);
732           break;
733 #endif
734       default:
735           printf ("Unknown type\n");
736           break;
737       }
738 }
739
740 void
741 print_cert_info_compact (gnutls_session_t session)
742 {
743
744     if (gnutls_certificate_client_get_request_status (session) != 0)
745         printf ("- Server has requested a certificate.\n");
746
747     switch (gnutls_certificate_type_get (session))
748       {
749       case GNUTLS_CRT_X509:
750           print_x509_info_compact (session);
751           break;
752 #ifdef ENABLE_OPENPGP
753       case GNUTLS_CRT_OPENPGP:
754           print_openpgp_info_compact (session);
755           break;
756 #endif
757       default:
758           printf ("Unknown type\n");
759           break;
760       }
761 }
762
763 void
764 print_list (const char *priorities, int verbose)
765 {
766     size_t i;
767     int ret;
768     unsigned int idx;
769     const char *name;
770     const char *err;
771     unsigned char id[2];
772     gnutls_kx_algorithm_t kx;
773     gnutls_cipher_algorithm_t cipher;
774     gnutls_mac_algorithm_t mac;
775     gnutls_protocol_t version;
776     gnutls_priority_t pcache;
777     const unsigned int *list;
778
779     if (priorities != NULL)
780       {
781           printf ("Cipher suites for %s\n", priorities);
782
783           ret = gnutls_priority_init (&pcache, priorities, &err);
784           if (ret < 0)
785             {
786                 fprintf (stderr, "Syntax error at: %s\n", err);
787                 exit (1);
788             }
789
790           for (i = 0;; i++)
791             {
792                 ret =
793                     gnutls_priority_get_cipher_suite_index (pcache, i,
794                                                             &idx);
795                 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
796                     break;
797                 if (ret == GNUTLS_E_UNKNOWN_CIPHER_SUITE)
798                     continue;
799
800                 name =
801                     gnutls_cipher_suite_info (idx, id, NULL, NULL, NULL,
802                                               &version);
803
804                 if (name != NULL)
805                     printf ("%-50s\t0x%02x, 0x%02x\t%s\n",
806                             name, (unsigned char) id[0],
807                             (unsigned char) id[1],
808                             gnutls_protocol_get_name (version));
809             }
810
811           printf("\n");
812           {
813               ret = gnutls_priority_certificate_type_list (pcache, &list);
814
815               printf ("Certificate types: ");
816               if (ret == 0) printf("none\n");
817               for (i = 0; i < (unsigned)ret; i++)
818                 {
819                     printf ("CTYPE-%s",
820                             gnutls_certificate_type_get_name (list[i]));
821                     if (i+1!=(unsigned)ret)
822                         printf (", ");
823                     else
824                         printf ("\n");
825                 }
826           }
827
828           {
829               ret = gnutls_priority_protocol_list (pcache, &list);
830
831               printf ("Protocols: ");
832               if (ret == 0) printf("none\n");
833               for (i = 0; i < (unsigned)ret; i++)
834                 {
835                     printf ("VERS-%s", gnutls_protocol_get_name (list[i]));
836                     if (i+1!=(unsigned)ret)
837                         printf (", ");
838                     else
839                         printf ("\n");
840                 }
841           }
842
843           {
844               ret = gnutls_priority_compression_list (pcache, &list);
845
846               printf ("Compression: ");
847               if (ret == 0) printf("none\n");
848               for (i = 0; i < (unsigned)ret; i++)
849                 {
850                     printf ("COMP-%s",
851                             gnutls_compression_get_name (list[i]));
852                     if (i+1!=(unsigned)ret)
853                         printf (", ");
854                     else
855                         printf ("\n");
856                 }
857           }
858
859           {
860               ret = gnutls_priority_ecc_curve_list (pcache, &list);
861
862               printf ("Elliptic curves: ");
863               if (ret == 0) printf("none\n");
864               for (i = 0; i < (unsigned)ret; i++)
865                 {
866                     printf ("CURVE-%s",
867                             gnutls_ecc_curve_get_name (list[i]));
868                     if (i+1!=(unsigned)ret)
869                         printf (", ");
870                     else
871                         printf ("\n");
872                 }
873           }
874
875           {
876               ret = gnutls_priority_sign_list (pcache, &list);
877
878               printf ("PK-signatures: ");
879               if (ret == 0) printf("none\n");
880               for (i = 0; i < (unsigned)ret; i++)
881                 {
882                     printf ("SIGN-%s",
883                             gnutls_sign_algorithm_get_name (list[i]));
884                     if (i+1!=(unsigned)ret)
885                         printf (", ");
886                     else
887                         printf ("\n");
888                 }
889           }
890
891           return;
892       }
893
894     printf ("Cipher suites:\n");
895     for (i = 0; (name = gnutls_cipher_suite_info
896                  (i, id, &kx, &cipher, &mac, &version)); i++)
897       {
898           printf ("%-50s\t0x%02x, 0x%02x\t%s\n",
899                   name,
900                   (unsigned char) id[0], (unsigned char) id[1],
901                   gnutls_protocol_get_name (version));
902           if (verbose)
903               printf ("\tKey exchange: %s\n\tCipher: %s\n\tMAC: %s\n\n",
904                       gnutls_kx_get_name (kx),
905                       gnutls_cipher_get_name (cipher),
906                       gnutls_mac_get_name (mac));
907       }
908
909     printf("\n");
910     {
911         const gnutls_certificate_type_t *p =
912             gnutls_certificate_type_list ();
913
914         printf ("Certificate types: ");
915         for (; *p; p++)
916           {
917               printf ("CTYPE-%s", gnutls_certificate_type_get_name (*p));
918               if (*(p + 1))
919                   printf (", ");
920               else
921                   printf ("\n");
922           }
923     }
924
925     {
926         const gnutls_protocol_t *p = gnutls_protocol_list ();
927
928         printf ("Protocols: ");
929         for (; *p; p++)
930           {
931               printf ("VERS-%s", gnutls_protocol_get_name (*p));
932               if (*(p + 1))
933                   printf (", ");
934               else
935                   printf ("\n");
936           }
937     }
938
939     {
940         const gnutls_cipher_algorithm_t *p = gnutls_cipher_list ();
941
942         printf ("Ciphers: ");
943         for (; *p; p++)
944           {
945               printf ("%s", gnutls_cipher_get_name (*p));
946               if (*(p + 1))
947                   printf (", ");
948               else
949                   printf ("\n");
950           }
951     }
952
953     {
954         const gnutls_mac_algorithm_t *p = gnutls_mac_list ();
955
956         printf ("MACs: ");
957         for (; *p; p++)
958           {
959               printf ("%s", gnutls_mac_get_name (*p));
960               if (*(p + 1))
961                   printf (", ");
962               else
963                   printf ("\n");
964           }
965     }
966
967     {
968         const gnutls_kx_algorithm_t *p = gnutls_kx_list ();
969
970         printf ("Key exchange algorithms: ");
971         for (; *p; p++)
972           {
973               printf ("%s", gnutls_kx_get_name (*p));
974               if (*(p + 1))
975                   printf (", ");
976               else
977                   printf ("\n");
978           }
979     }
980
981     {
982         const gnutls_compression_method_t *p = gnutls_compression_list ();
983
984         printf ("Compression: ");
985         for (; *p; p++)
986           {
987               printf ("COMP-%s", gnutls_compression_get_name (*p));
988               if (*(p + 1))
989                   printf (", ");
990               else
991                   printf ("\n");
992           }
993     }
994
995     {
996         const gnutls_ecc_curve_t *p = gnutls_ecc_curve_list ();
997
998         printf ("Elliptic curves: ");
999         for (; *p; p++)
1000           {
1001               printf ("CURVE-%s", gnutls_ecc_curve_get_name (*p));
1002               if (*(p + 1))
1003                   printf (", ");
1004               else
1005                   printf ("\n");
1006           }
1007     }
1008
1009     {
1010         const gnutls_pk_algorithm_t *p = gnutls_pk_list ();
1011
1012         printf ("Public Key Systems: ");
1013         for (; *p; p++)
1014           {
1015               printf ("%s", gnutls_pk_algorithm_get_name (*p));
1016               if (*(p + 1))
1017                   printf (", ");
1018               else
1019                   printf ("\n");
1020           }
1021     }
1022
1023     {
1024         const gnutls_sign_algorithm_t *p = gnutls_sign_list ();
1025
1026         printf ("PK-signatures: ");
1027         for (; *p; p++)
1028           {
1029               printf ("SIGN-%s", gnutls_sign_algorithm_get_name (*p));
1030               if (*(p + 1))
1031                   printf (", ");
1032               else
1033                   printf ("\n");
1034           }
1035     }
1036 }
1037
1038 int check_command(gnutls_session_t session, const char* str)
1039 {
1040 int len = strlen(str);
1041
1042   if (len > 2 && str[0] == str[1] && str[0] == '*')
1043     {
1044       if (strncmp(str, "**REHANDSHAKE**",
1045           sizeof ("**REHANDSHAKE**") - 1) == 0)
1046         {
1047           fprintf (stderr, "*** Sending rehandshake request\n");
1048                    gnutls_rehandshake (session);
1049           return 1;
1050         }
1051     }
1052   return 0;
1053 }