Allow for bit strings that are not a multiple of 8.
[gnutls.git] / src / common.c
blob412e776dc8625d0b91bdb8b60a7994b15db9b211
1 /*
2 * Copyright (C) 2000-2012 Free Software Foundation, Inc.
3 * Author: Nikos Mavrogiannopoulos
5 * This file is part of GnuTLS.
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.
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.
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/>.
21 #include <config.h>
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
29 #include <getpass.h>
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 <gnutls/crypto.h>
38 #include <time.h>
39 #include <common.h>
41 #ifdef ENABLE_PKCS11
42 # include <gnutls/pkcs11.h>
43 #endif
45 #define SU(x) (x!=NULL?x:"Unknown")
47 const char str_unknown[] = "(unknown)";
49 /* Hex encodes the given data.
51 const char *
52 raw_to_string (const unsigned char *raw, size_t raw_size)
54 static char buf[1024];
55 size_t i;
56 if (raw_size == 0)
57 return "(empty)";
59 if (raw_size * 3 + 1 >= sizeof (buf))
60 return "(too large)";
62 for (i = 0; i < raw_size; i++)
64 sprintf (&(buf[i * 3]), "%02X%s", raw[i],
65 (i == raw_size - 1) ? "" : ":");
67 buf[sizeof (buf) - 1] = '\0';
69 return buf;
72 static void
73 print_x509_info_compact (gnutls_session_t session)
75 gnutls_x509_crt_t crt;
76 const gnutls_datum_t *cert_list;
77 unsigned int cert_list_size = 0;
78 int ret;
79 gnutls_datum_t cinfo;
81 cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
82 if (cert_list_size == 0)
84 fprintf (stderr, "No certificates found!\n");
85 return;
88 gnutls_x509_crt_init (&crt);
89 ret =
90 gnutls_x509_crt_import (crt, &cert_list[0],
91 GNUTLS_X509_FMT_DER);
92 if (ret < 0)
94 fprintf (stderr, "Decoding error: %s\n",
95 gnutls_strerror (ret));
96 return;
99 ret =
100 gnutls_x509_crt_print (crt, GNUTLS_CRT_PRINT_COMPACT, &cinfo);
101 if (ret == 0)
103 printf ("- X.509 cert: %s\n", cinfo.data);
104 gnutls_free (cinfo.data);
107 gnutls_x509_crt_deinit (crt);
110 static void
111 print_x509_info (gnutls_session_t session, int flag, int print_cert)
113 gnutls_x509_crt_t crt;
114 const gnutls_datum_t *cert_list;
115 unsigned int cert_list_size = 0, j;
116 int ret;
118 cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
119 if (cert_list_size == 0)
121 fprintf (stderr, "No certificates found!\n");
122 return;
125 printf ("- Certificate type: X.509\n");
126 printf ("- Got a certificate list of %d certificates.\n",
127 cert_list_size);
129 for (j = 0; j < cert_list_size; j++)
131 gnutls_datum_t cinfo;
133 gnutls_x509_crt_init (&crt);
134 ret =
135 gnutls_x509_crt_import (crt, &cert_list[j],
136 GNUTLS_X509_FMT_DER);
137 if (ret < 0)
139 fprintf (stderr, "Decoding error: %s\n",
140 gnutls_strerror (ret));
141 return;
144 printf ("- Certificate[%d] info:\n - ", j);
145 if (flag == GNUTLS_CRT_PRINT_COMPACT && j > 0) flag = GNUTLS_CRT_PRINT_ONELINE;
147 ret =
148 gnutls_x509_crt_print (crt, flag, &cinfo);
149 if (ret == 0)
151 printf ("%s\n", cinfo.data);
152 gnutls_free (cinfo.data);
155 if (print_cert)
157 size_t size = 0;
158 char *p = NULL;
160 ret =
161 gnutls_x509_crt_export (crt, GNUTLS_X509_FMT_PEM, p,
162 &size);
163 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
165 p = malloc (size+1);
166 if (!p)
168 fprintf (stderr, "gnutls_malloc\n");
169 exit (1);
172 ret =
173 gnutls_x509_crt_export (crt, GNUTLS_X509_FMT_PEM,
174 p, &size);
176 if (ret < 0)
178 fprintf (stderr, "Encoding error: %s\n",
179 gnutls_strerror (ret));
180 return;
183 p[size] = 0;
184 fputs ("\n", stdout);
185 fputs (p, stdout);
186 fputs ("\n", stdout);
188 gnutls_free (p);
191 gnutls_x509_crt_deinit (crt);
195 #ifdef ENABLE_OPENPGP
196 static void
197 print_openpgp_info_compact (gnutls_session_t session)
200 gnutls_openpgp_crt_t crt;
201 const gnutls_datum_t *cert_list;
202 unsigned int cert_list_size = 0;
203 int ret;
205 cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
207 if (cert_list_size > 0)
209 gnutls_datum_t cinfo;
211 gnutls_openpgp_crt_init (&crt);
212 ret = gnutls_openpgp_crt_import (crt, &cert_list[0],
213 GNUTLS_OPENPGP_FMT_RAW);
214 if (ret < 0)
216 fprintf (stderr, "Decoding error: %s\n",
217 gnutls_strerror (ret));
218 return;
221 ret =
222 gnutls_openpgp_crt_print (crt, GNUTLS_CRT_PRINT_COMPACT, &cinfo);
223 if (ret == 0)
225 printf ("- OpenPGP cert: %s\n", cinfo.data);
226 gnutls_free (cinfo.data);
229 gnutls_openpgp_crt_deinit (crt);
233 static void
234 print_openpgp_info (gnutls_session_t session, int flag, int print_cert)
237 gnutls_openpgp_crt_t crt;
238 const gnutls_datum_t *cert_list;
239 unsigned int cert_list_size = 0;
240 int ret;
242 printf ("- Certificate type: OpenPGP\n");
244 cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
246 if (cert_list_size > 0)
248 gnutls_datum_t cinfo;
250 gnutls_openpgp_crt_init (&crt);
251 ret = gnutls_openpgp_crt_import (crt, &cert_list[0],
252 GNUTLS_OPENPGP_FMT_RAW);
253 if (ret < 0)
255 fprintf (stderr, "Decoding error: %s\n",
256 gnutls_strerror (ret));
257 return;
260 ret =
261 gnutls_openpgp_crt_print (crt, flag, &cinfo);
262 if (ret == 0)
264 printf ("- %s\n", cinfo.data);
265 gnutls_free (cinfo.data);
268 if (print_cert)
270 size_t size = 0;
271 char *p = NULL;
273 ret =
274 gnutls_openpgp_crt_export (crt,
275 GNUTLS_OPENPGP_FMT_BASE64,
276 p, &size);
277 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
279 p = malloc (size);
280 if (!p)
282 fprintf (stderr, "gnutls_malloc\n");
283 exit (1);
286 ret =
287 gnutls_openpgp_crt_export (crt,
288 GNUTLS_OPENPGP_FMT_BASE64,
289 p, &size);
291 if (ret < 0)
293 fprintf (stderr, "Encoding error: %s\n",
294 gnutls_strerror (ret));
295 return;
298 fputs (p, stdout);
299 fputs ("\n", stdout);
301 gnutls_free (p);
304 gnutls_openpgp_crt_deinit (crt);
308 #endif
310 /* returns false (0) if not verified, or true (1) otherwise
313 cert_verify (gnutls_session_t session, const char* hostname)
315 int rc;
316 unsigned int status = 0;
317 gnutls_datum_t out;
318 int type;
320 rc = gnutls_certificate_verify_peers3 (session, hostname, &status);
321 if (rc == GNUTLS_E_NO_CERTIFICATE_FOUND)
323 printf ("- Peer did not send any certificate.\n");
324 return 0;
327 if (rc < 0)
329 printf ("- Could not verify certificate (err: %s)\n",
330 gnutls_strerror (rc));
331 return 0;
334 type = gnutls_certificate_type_get (session);
335 rc = gnutls_certificate_verification_status_print( status, type, &out, 0);
336 if (rc < 0)
338 printf ("- Could not print verification flags (err: %s)\n",
339 gnutls_strerror (rc));
340 return 0;
343 printf ("- Status: %s\n", out.data);
345 gnutls_free(out.data);
347 if (status)
348 return 0;
350 return 1;
353 static void
354 print_dh_info (gnutls_session_t session, const char *str, int print)
356 printf ("- %sDiffie-Hellman parameters\n", str);
357 printf (" - Using prime: %d bits\n",
358 gnutls_dh_get_prime_bits (session));
359 printf (" - Secret key: %d bits\n",
360 gnutls_dh_get_secret_bits (session));
361 printf (" - Peer's public key: %d bits\n",
362 gnutls_dh_get_peers_public_bits (session));
364 if (print)
366 int ret;
367 gnutls_datum_t raw_gen = { NULL, 0 };
368 gnutls_datum_t raw_prime = { NULL, 0 };
369 gnutls_dh_params_t dh_params = NULL;
370 unsigned char *params_data = NULL;
371 size_t params_data_size = 0;
373 ret = gnutls_dh_get_group (session, &raw_gen, &raw_prime);
374 if (ret)
376 fprintf (stderr, "gnutls_dh_get_group %d\n", ret);
377 goto out;
380 ret = gnutls_dh_params_init (&dh_params);
381 if (ret)
383 fprintf (stderr, "gnutls_dh_params_init %d\n", ret);
384 goto out;
387 ret =
388 gnutls_dh_params_import_raw (dh_params, &raw_prime,
389 &raw_gen);
390 if (ret)
392 fprintf (stderr, "gnutls_dh_params_import_raw %d\n", ret);
393 goto out;
396 ret = gnutls_dh_params_export_pkcs3 (dh_params,
397 GNUTLS_X509_FMT_PEM,
398 params_data,
399 &params_data_size);
400 if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
402 fprintf (stderr, "gnutls_dh_params_export_pkcs3 %d\n",
403 ret);
404 goto out;
407 params_data = gnutls_malloc (params_data_size);
408 if (!params_data)
410 fprintf (stderr, "gnutls_malloc %d\n", ret);
411 goto out;
414 ret = gnutls_dh_params_export_pkcs3 (dh_params,
415 GNUTLS_X509_FMT_PEM,
416 params_data,
417 &params_data_size);
418 if (ret)
420 fprintf (stderr, "gnutls_dh_params_export_pkcs3-2 %d\n",
421 ret);
422 goto out;
425 printf (" - PKCS#3 format:\n\n%.*s\n", (int) params_data_size,
426 params_data);
428 out:
429 gnutls_free (params_data);
430 gnutls_free (raw_prime.data);
431 gnutls_free (raw_gen.data);
432 gnutls_dh_params_deinit (dh_params);
436 static void
437 print_ecdh_info (gnutls_session_t session, const char *str)
439 int curve;
441 printf ("- %sEC Diffie-Hellman parameters\n", str);
443 curve = gnutls_ecc_curve_get (session);
445 printf (" - Using curve: %s\n", gnutls_ecc_curve_get_name (curve));
446 printf (" - Curve size: %d bits\n",
447 gnutls_ecc_curve_get_size (curve) * 8);
452 print_info (gnutls_session_t session, int verbose, int print_cert)
454 const char *tmp;
455 gnutls_credentials_type_t cred;
456 gnutls_kx_algorithm_t kx;
457 unsigned char session_id[33];
458 size_t session_id_size = sizeof (session_id);
459 gnutls_srtp_profile_t srtp_profile;
460 int rc;
462 /* print session ID */
463 gnutls_session_get_id (session, session_id, &session_id_size);
464 printf ("- Session ID: %s\n",
465 raw_to_string (session_id, session_id_size));
467 /* print the key exchange's algorithm name
469 kx = gnutls_kx_get (session);
471 cred = gnutls_auth_get_type (session);
472 switch (cred)
474 #ifdef ENABLE_ANON
475 case GNUTLS_CRD_ANON:
476 if (kx == GNUTLS_KX_ANON_ECDH)
477 print_ecdh_info (session, "Anonymous ");
478 else
479 print_dh_info (session, "Anonymous ", verbose);
480 break;
481 #endif
482 #ifdef ENABLE_SRP
483 case GNUTLS_CRD_SRP:
484 /* This should be only called in server
485 * side.
487 if (gnutls_srp_server_get_username (session) != NULL)
488 printf ("- SRP authentication. Connected as '%s'\n",
489 gnutls_srp_server_get_username (session));
490 break;
491 #endif
492 #ifdef ENABLE_PSK
493 case GNUTLS_CRD_PSK:
494 /* This returns NULL in server side.
496 if (gnutls_psk_client_get_hint (session) != NULL)
497 printf ("- PSK authentication. PSK hint '%s'\n",
498 gnutls_psk_client_get_hint (session));
499 /* This returns NULL in client side.
501 if (gnutls_psk_server_get_username (session) != NULL)
502 printf ("- PSK authentication. Connected as '%s'\n",
503 gnutls_psk_server_get_username (session));
504 if (kx == GNUTLS_KX_DHE_PSK)
505 print_dh_info (session, "Ephemeral ", verbose);
506 if (kx == GNUTLS_KX_ECDHE_PSK)
507 print_ecdh_info (session, "Ephemeral ");
508 break;
509 #endif
510 case GNUTLS_CRD_IA:
511 printf ("- TLS/IA authentication\n");
512 break;
513 case GNUTLS_CRD_CERTIFICATE:
515 char dns[256];
516 size_t dns_size = sizeof (dns);
517 unsigned int type;
519 /* This fails in client side */
520 if (gnutls_server_name_get
521 (session, dns, &dns_size, &type, 0) == 0)
523 printf ("- Given server name[%d]: %s\n", type, dns);
527 if (print_cert)
528 print_cert_info (session, verbose, print_cert);
530 if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS)
531 print_dh_info (session, "Ephemeral ", verbose);
532 else if (kx == GNUTLS_KX_ECDHE_RSA
533 || kx == GNUTLS_KX_ECDHE_ECDSA)
534 print_ecdh_info (session, "Ephemeral ");
537 tmp =
538 SU (gnutls_protocol_get_name
539 (gnutls_protocol_get_version (session)));
540 printf ("- Version: %s\n", tmp);
542 tmp = SU (gnutls_kx_get_name (kx));
543 printf ("- Key Exchange: %s\n", tmp);
545 tmp = SU (gnutls_cipher_get_name (gnutls_cipher_get (session)));
546 printf ("- Cipher: %s\n", tmp);
548 tmp = SU (gnutls_mac_get_name (gnutls_mac_get (session)));
549 printf ("- MAC: %s\n", tmp);
551 tmp =
552 SU (gnutls_compression_get_name
553 (gnutls_compression_get (session)));
554 printf ("- Compression: %s\n", tmp);
556 #ifdef ENABLE_DTLS_SRTP
557 rc = gnutls_srtp_get_selected_profile (session, &srtp_profile);
558 if (rc == 0)
559 printf ("- SRTP profile: %s\n", gnutls_srtp_get_profile_name (srtp_profile));
560 #endif
562 if (verbose)
564 gnutls_datum_t cb;
566 rc = gnutls_session_channel_binding (session,
567 GNUTLS_CB_TLS_UNIQUE, &cb);
568 if (rc)
569 fprintf (stderr, "Channel binding error: %s\n",
570 gnutls_strerror (rc));
571 else
573 size_t i;
575 printf ("- Channel binding 'tls-unique': ");
576 for (i = 0; i < cb.size; i++)
577 printf ("%02x", cb.data[i]);
578 printf ("\n");
582 /* Warning: Do not print anything more here. The 'Compression:'
583 output MUST be the last non-verbose output. This is used by
584 Emacs starttls.el code. */
586 fflush (stdout);
588 return 0;
591 void
592 print_cert_info (gnutls_session_t session, int verbose, int print_cert)
594 int flag;
596 if (verbose) flag = GNUTLS_CRT_PRINT_FULL;
597 else flag = GNUTLS_CRT_PRINT_COMPACT;
599 if (gnutls_certificate_client_get_request_status (session) != 0)
600 printf ("- Server has requested a certificate.\n");
602 switch (gnutls_certificate_type_get (session))
604 case GNUTLS_CRT_X509:
605 print_x509_info (session, flag, print_cert);
606 break;
607 #ifdef ENABLE_OPENPGP
608 case GNUTLS_CRT_OPENPGP:
609 print_openpgp_info (session, flag, print_cert);
610 break;
611 #endif
612 default:
613 printf ("Unknown type\n");
614 break;
618 void
619 print_cert_info_compact (gnutls_session_t session)
622 if (gnutls_certificate_client_get_request_status (session) != 0)
623 printf ("- Server has requested a certificate.\n");
625 switch (gnutls_certificate_type_get (session))
627 case GNUTLS_CRT_X509:
628 print_x509_info_compact (session);
629 break;
630 #ifdef ENABLE_OPENPGP
631 case GNUTLS_CRT_OPENPGP:
632 print_openpgp_info_compact (session);
633 break;
634 #endif
635 default:
636 printf ("Unknown type\n");
637 break;
641 void
642 print_list (const char *priorities, int verbose)
644 size_t i;
645 int ret;
646 unsigned int idx;
647 const char *name;
648 const char *err;
649 unsigned char id[2];
650 gnutls_kx_algorithm_t kx;
651 gnutls_cipher_algorithm_t cipher;
652 gnutls_mac_algorithm_t mac;
653 gnutls_protocol_t version;
654 gnutls_priority_t pcache;
655 const unsigned int *list;
657 if (priorities != NULL)
659 printf ("Cipher suites for %s\n", priorities);
661 ret = gnutls_priority_init (&pcache, priorities, &err);
662 if (ret < 0)
664 fprintf (stderr, "Syntax error at: %s\n", err);
665 exit (1);
668 for (i = 0;; i++)
670 ret =
671 gnutls_priority_get_cipher_suite_index (pcache, i,
672 &idx);
673 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
674 break;
675 if (ret == GNUTLS_E_UNKNOWN_CIPHER_SUITE)
676 continue;
678 name =
679 gnutls_cipher_suite_info (idx, id, NULL, NULL, NULL,
680 &version);
682 if (name != NULL)
683 printf ("%-50s\t0x%02x, 0x%02x\t%s\n",
684 name, (unsigned char) id[0],
685 (unsigned char) id[1],
686 gnutls_protocol_get_name (version));
689 printf("\n");
691 ret = gnutls_priority_certificate_type_list (pcache, &list);
693 printf ("Certificate types: ");
694 if (ret == 0) printf("none\n");
695 for (i = 0; i < (unsigned)ret; i++)
697 printf ("CTYPE-%s",
698 gnutls_certificate_type_get_name (list[i]));
699 if (i+1!=(unsigned)ret)
700 printf (", ");
701 else
702 printf ("\n");
707 ret = gnutls_priority_protocol_list (pcache, &list);
709 printf ("Protocols: ");
710 if (ret == 0) printf("none\n");
711 for (i = 0; i < (unsigned)ret; i++)
713 printf ("VERS-%s", gnutls_protocol_get_name (list[i]));
714 if (i+1!=(unsigned)ret)
715 printf (", ");
716 else
717 printf ("\n");
722 ret = gnutls_priority_compression_list (pcache, &list);
724 printf ("Compression: ");
725 if (ret == 0) printf("none\n");
726 for (i = 0; i < (unsigned)ret; i++)
728 printf ("COMP-%s",
729 gnutls_compression_get_name (list[i]));
730 if (i+1!=(unsigned)ret)
731 printf (", ");
732 else
733 printf ("\n");
738 ret = gnutls_priority_ecc_curve_list (pcache, &list);
740 printf ("Elliptic curves: ");
741 if (ret == 0) printf("none\n");
742 for (i = 0; i < (unsigned)ret; i++)
744 printf ("CURVE-%s",
745 gnutls_ecc_curve_get_name (list[i]));
746 if (i+1!=(unsigned)ret)
747 printf (", ");
748 else
749 printf ("\n");
754 ret = gnutls_priority_sign_list (pcache, &list);
756 printf ("PK-signatures: ");
757 if (ret == 0) printf("none\n");
758 for (i = 0; i < (unsigned)ret; i++)
760 printf ("SIGN-%s",
761 gnutls_sign_algorithm_get_name (list[i]));
762 if (i+1!=(unsigned)ret)
763 printf (", ");
764 else
765 printf ("\n");
769 return;
772 printf ("Cipher suites:\n");
773 for (i = 0; (name = gnutls_cipher_suite_info
774 (i, id, &kx, &cipher, &mac, &version)); i++)
776 printf ("%-50s\t0x%02x, 0x%02x\t%s\n",
777 name,
778 (unsigned char) id[0], (unsigned char) id[1],
779 gnutls_protocol_get_name (version));
780 if (verbose)
781 printf ("\tKey exchange: %s\n\tCipher: %s\n\tMAC: %s\n\n",
782 gnutls_kx_get_name (kx),
783 gnutls_cipher_get_name (cipher),
784 gnutls_mac_get_name (mac));
787 printf("\n");
789 const gnutls_certificate_type_t *p =
790 gnutls_certificate_type_list ();
792 printf ("Certificate types: ");
793 for (; *p; p++)
795 printf ("CTYPE-%s", gnutls_certificate_type_get_name (*p));
796 if (*(p + 1))
797 printf (", ");
798 else
799 printf ("\n");
804 const gnutls_protocol_t *p = gnutls_protocol_list ();
806 printf ("Protocols: ");
807 for (; *p; p++)
809 printf ("VERS-%s", gnutls_protocol_get_name (*p));
810 if (*(p + 1))
811 printf (", ");
812 else
813 printf ("\n");
818 const gnutls_cipher_algorithm_t *p = gnutls_cipher_list ();
820 printf ("Ciphers: ");
821 for (; *p; p++)
823 printf ("%s", gnutls_cipher_get_name (*p));
824 if (*(p + 1))
825 printf (", ");
826 else
827 printf ("\n");
832 const gnutls_mac_algorithm_t *p = gnutls_mac_list ();
834 printf ("MACs: ");
835 for (; *p; p++)
837 printf ("%s", gnutls_mac_get_name (*p));
838 if (*(p + 1))
839 printf (", ");
840 else
841 printf ("\n");
846 const gnutls_kx_algorithm_t *p = gnutls_kx_list ();
848 printf ("Key exchange algorithms: ");
849 for (; *p; p++)
851 printf ("%s", gnutls_kx_get_name (*p));
852 if (*(p + 1))
853 printf (", ");
854 else
855 printf ("\n");
860 const gnutls_compression_method_t *p = gnutls_compression_list ();
862 printf ("Compression: ");
863 for (; *p; p++)
865 printf ("COMP-%s", gnutls_compression_get_name (*p));
866 if (*(p + 1))
867 printf (", ");
868 else
869 printf ("\n");
874 const gnutls_ecc_curve_t *p = gnutls_ecc_curve_list ();
876 printf ("Elliptic curves: ");
877 for (; *p; p++)
879 printf ("CURVE-%s", gnutls_ecc_curve_get_name (*p));
880 if (*(p + 1))
881 printf (", ");
882 else
883 printf ("\n");
888 const gnutls_pk_algorithm_t *p = gnutls_pk_list ();
890 printf ("Public Key Systems: ");
891 for (; *p; p++)
893 printf ("%s", gnutls_pk_algorithm_get_name (*p));
894 if (*(p + 1))
895 printf (", ");
896 else
897 printf ("\n");
902 const gnutls_sign_algorithm_t *p = gnutls_sign_list ();
904 printf ("PK-signatures: ");
905 for (; *p; p++)
907 printf ("SIGN-%s", gnutls_sign_algorithm_get_name (*p));
908 if (*(p + 1))
909 printf (", ");
910 else
911 printf ("\n");
916 int check_command(gnutls_session_t session, const char* str)
918 size_t len = strnlen(str, 128);
919 int ret;
921 fprintf (stderr, "*** Processing %zu bytes command: %s\n", len, str);
922 if (len > 2 && str[0] == str[1] && str[0] == '*')
924 if (strncmp(str, "**REHANDSHAKE**", sizeof ("**REHANDSHAKE**") - 1) == 0)
926 fprintf (stderr, "*** Sending rehandshake request\n");
927 gnutls_rehandshake (session);
928 return 1;
929 } else if (strncmp(str, "**HEARTBEAT**", sizeof ("**HEARTBEAT**") - 1) == 0) {
930 ret = gnutls_heartbeat_ping (session, 300, 5, GNUTLS_HEARTBEAT_WAIT);
931 if (ret < 0)
933 if (ret == GNUTLS_E_INVALID_REQUEST)
935 fprintf(stderr, "No heartbeat in this session\n");
937 else
939 fprintf(stderr, "ping: %s\n", gnutls_strerror(ret));
940 exit(1);
943 return 2;
946 return 0;
949 #define MIN(x,y) ((x)<(y))?(x):(y)
950 #define MAX_CACHE_TRIES 5
952 pin_callback (void *user, int attempt, const char *token_url,
953 const char *token_label, unsigned int flags, char *pin,
954 size_t pin_max)
956 const char *password;
957 const char * desc;
958 int len, cache = MAX_CACHE_TRIES;
959 /* allow caching of PIN */
960 static char *cached_url = NULL;
961 static char cached_pin[32] = "";
963 if (flags & GNUTLS_PIN_SO)
964 desc = "security officer";
965 else
966 desc = "user";
968 if (flags & GNUTLS_PIN_FINAL_TRY)
970 cache = 0;
971 printf ("*** This is the final try before locking!\n");
973 if (flags & GNUTLS_PIN_COUNT_LOW)
975 cache = 0;
976 printf ("*** Only few tries left before locking!\n");
979 if (flags & GNUTLS_PIN_WRONG)
981 cache = 0;
982 printf ("*** Wrong PIN has been provided!\n");
985 if (cache > 0 && cached_url != NULL)
987 if (strcmp (cached_url, token_url) == 0)
989 if (strlen(pin) >= sizeof(cached_pin))
991 fprintf (stderr, "Too long PIN given\n");
992 exit (1);
995 fprintf(stderr, "Re-using cached PIN for token '%s'\n", token_label);
996 strcpy (pin, cached_pin);
997 cache--;
998 return 0;
1002 printf ("Token '%s' with URL '%s' ", token_label, token_url);
1003 printf ("requires %s PIN\n", desc);
1005 password = getpass ("Enter PIN: ");
1006 if (password == NULL || password[0] == 0)
1008 fprintf (stderr, "No password given\n");
1009 exit (1);
1012 len = MIN (pin_max, strlen (password));
1013 memcpy (pin, password, len);
1014 pin[len] = 0;
1016 /* cache */
1017 strcpy (cached_pin, pin);
1018 free (cached_url);
1019 cached_url = strdup (token_url);
1020 cache = MAX_CACHE_TRIES;
1022 return 0;
1025 #ifdef ENABLE_PKCS11
1027 static int
1028 token_callback (void *user, const char *label, const unsigned retry)
1030 char buf[32];
1032 if (retry > 0)
1034 fprintf (stderr, "Could not find token %s\n", label);
1035 return -1;
1037 printf ("Please insert token '%s' in slot and press enter\n", label);
1038 fgets (buf, sizeof (buf), stdin);
1040 return 0;
1043 void
1044 pkcs11_common (void)
1047 gnutls_pkcs11_set_pin_function (pin_callback, NULL);
1048 gnutls_pkcs11_set_token_function (token_callback, NULL);
1052 #endif