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/>.
23 /* Work around problem reported in
24 <http://permalink.gmane.org/gmane.comp.lib.gnulib.bugs/15755>.*/
25 #if GETTIMEOFDAY_CLOBBERS_LOCALTIME
34 #include <gnutls/gnutls.h>
35 #include <gnutls/x509.h>
36 #include <gnutls/openpgp.h>
37 #include <gnutls/crypto.h>
42 # include <gnutls/pkcs11.h>
45 #define SU(x) (x!=NULL?x:"Unknown")
47 const char str_unknown
[] = "(unknown)";
49 /* Hex encodes the given data.
52 raw_to_string (const unsigned char *raw
, size_t raw_size
)
54 static char buf
[1024];
59 if (raw_size
* 3 + 1 >= sizeof (buf
))
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';
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;
81 cert_list
= gnutls_certificate_get_peers (session
, &cert_list_size
);
82 if (cert_list_size
== 0)
84 fprintf (stderr
, "No certificates found!\n");
88 gnutls_x509_crt_init (&crt
);
90 gnutls_x509_crt_import (crt
, &cert_list
[0],
94 fprintf (stderr
, "Decoding error: %s\n",
95 gnutls_strerror (ret
));
100 gnutls_x509_crt_print (crt
, GNUTLS_CRT_PRINT_COMPACT
, &cinfo
);
103 printf ("- X.509 cert: %s\n", cinfo
.data
);
104 gnutls_free (cinfo
.data
);
107 gnutls_x509_crt_deinit (crt
);
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
;
118 cert_list
= gnutls_certificate_get_peers (session
, &cert_list_size
);
119 if (cert_list_size
== 0)
121 fprintf (stderr
, "No certificates found!\n");
125 printf ("- Certificate type: X.509\n");
126 printf ("- Got a certificate list of %d certificates.\n",
129 for (j
= 0; j
< cert_list_size
; j
++)
131 gnutls_datum_t cinfo
;
133 gnutls_x509_crt_init (&crt
);
135 gnutls_x509_crt_import (crt
, &cert_list
[j
],
136 GNUTLS_X509_FMT_DER
);
139 fprintf (stderr
, "Decoding error: %s\n",
140 gnutls_strerror (ret
));
144 printf ("- Certificate[%d] info:\n - ", j
);
145 if (flag
== GNUTLS_CRT_PRINT_COMPACT
&& j
> 0) flag
= GNUTLS_CRT_PRINT_ONELINE
;
148 gnutls_x509_crt_print (crt
, flag
, &cinfo
);
151 printf ("%s\n", cinfo
.data
);
152 gnutls_free (cinfo
.data
);
161 gnutls_x509_crt_export (crt
, GNUTLS_X509_FMT_PEM
, p
,
163 if (ret
== GNUTLS_E_SHORT_MEMORY_BUFFER
)
168 fprintf (stderr
, "gnutls_malloc\n");
173 gnutls_x509_crt_export (crt
, GNUTLS_X509_FMT_PEM
,
178 fprintf (stderr
, "Encoding error: %s\n",
179 gnutls_strerror (ret
));
184 fputs ("\n", stdout
);
186 fputs ("\n", stdout
);
191 gnutls_x509_crt_deinit (crt
);
195 /* returns true or false, depending on whether the hostname
196 * matches to certificate */
198 verify_x509_hostname (gnutls_session_t session
, const char *hostname
)
200 gnutls_x509_crt_t crt
;
201 const gnutls_datum_t
*cert_list
;
202 unsigned int cert_list_size
= 0;
205 cert_list
= gnutls_certificate_get_peers (session
, &cert_list_size
);
206 if (cert_list_size
== 0)
208 fprintf (stderr
, "No certificates found!\n");
212 gnutls_x509_crt_init (&crt
);
214 gnutls_x509_crt_import (crt
, &cert_list
[0],
215 GNUTLS_X509_FMT_DER
);
218 fprintf (stderr
, "Decoding error: %s\n",
219 gnutls_strerror (ret
));
223 /* Check the hostname of the first certificate if it matches
224 * the name of the host we connected to.
226 if (hostname
!= NULL
)
228 if (gnutls_x509_crt_check_hostname (crt
, hostname
) == 0)
231 ("- The hostname in the certificate does NOT match '%s'\n",
237 printf ("- The hostname in the certificate matches '%s'.\n",
243 gnutls_x509_crt_deinit (crt
);
248 #ifdef ENABLE_OPENPGP
249 /* returns true or false, depending on whether the hostname
250 * matches to certificate */
252 verify_openpgp_hostname (gnutls_session_t session
, const char *hostname
)
254 gnutls_openpgp_crt_t crt
;
255 const gnutls_datum_t
*cert_list
;
256 unsigned int cert_list_size
= 0;
259 cert_list
= gnutls_certificate_get_peers (session
, &cert_list_size
);
260 if (cert_list_size
== 0)
262 fprintf (stderr
, "No certificates found!\n");
266 gnutls_openpgp_crt_init (&crt
);
268 gnutls_openpgp_crt_import (crt
, &cert_list
[0],
269 GNUTLS_OPENPGP_FMT_RAW
);
272 fprintf (stderr
, "Decoding error: %s\n",
273 gnutls_strerror (ret
));
277 /* Check the hostname of the first certificate if it matches
278 * the name of the host we connected to.
280 if (gnutls_openpgp_crt_check_hostname (crt
, hostname
) == 0)
283 ("- The hostname in the certificate does NOT match '%s'\n",
289 printf ("- The hostname in the certificate matches '%s'.\n",
294 gnutls_openpgp_crt_deinit (crt
);
300 print_openpgp_info_compact (gnutls_session_t session
)
303 gnutls_openpgp_crt_t crt
;
304 const gnutls_datum_t
*cert_list
;
305 unsigned int cert_list_size
= 0;
308 cert_list
= gnutls_certificate_get_peers (session
, &cert_list_size
);
310 if (cert_list_size
> 0)
312 gnutls_datum_t cinfo
;
314 gnutls_openpgp_crt_init (&crt
);
315 ret
= gnutls_openpgp_crt_import (crt
, &cert_list
[0],
316 GNUTLS_OPENPGP_FMT_RAW
);
319 fprintf (stderr
, "Decoding error: %s\n",
320 gnutls_strerror (ret
));
325 gnutls_openpgp_crt_print (crt
, GNUTLS_CRT_PRINT_COMPACT
, &cinfo
);
328 printf ("- OpenPGP cert: %s\n", cinfo
.data
);
329 gnutls_free (cinfo
.data
);
332 gnutls_openpgp_crt_deinit (crt
);
337 print_openpgp_info (gnutls_session_t session
, int flag
, int print_cert
)
340 gnutls_openpgp_crt_t crt
;
341 const gnutls_datum_t
*cert_list
;
342 unsigned int cert_list_size
= 0;
345 printf ("- Certificate type: OpenPGP\n");
347 cert_list
= gnutls_certificate_get_peers (session
, &cert_list_size
);
349 if (cert_list_size
> 0)
351 gnutls_datum_t cinfo
;
353 gnutls_openpgp_crt_init (&crt
);
354 ret
= gnutls_openpgp_crt_import (crt
, &cert_list
[0],
355 GNUTLS_OPENPGP_FMT_RAW
);
358 fprintf (stderr
, "Decoding error: %s\n",
359 gnutls_strerror (ret
));
364 gnutls_openpgp_crt_print (crt
, flag
, &cinfo
);
367 printf ("- %s\n", cinfo
.data
);
368 gnutls_free (cinfo
.data
);
377 gnutls_openpgp_crt_export (crt
,
378 GNUTLS_OPENPGP_FMT_BASE64
,
380 if (ret
== GNUTLS_E_SHORT_MEMORY_BUFFER
)
385 fprintf (stderr
, "gnutls_malloc\n");
390 gnutls_openpgp_crt_export (crt
,
391 GNUTLS_OPENPGP_FMT_BASE64
,
396 fprintf (stderr
, "Encoding error: %s\n",
397 gnutls_strerror (ret
));
402 fputs ("\n", stdout
);
407 gnutls_openpgp_crt_deinit (crt
);
413 /* returns false (0) if not verified, or true (1) otherwise
416 cert_verify (gnutls_session_t session
, const char* hostname
)
419 unsigned int status
= 0;
422 rc
= gnutls_certificate_verify_peers2 (session
, &status
);
423 if (rc
== GNUTLS_E_NO_CERTIFICATE_FOUND
)
425 printf ("- Peer did not send any certificate.\n");
431 printf ("- Could not verify certificate (err: %s)\n",
432 gnutls_strerror (rc
));
436 type
= gnutls_certificate_type_get (session
);
437 if (type
== GNUTLS_CRT_X509
)
440 if (status
& GNUTLS_CERT_REVOKED
)
441 printf ("- Peer's certificate chain revoked\n");
442 if (status
& GNUTLS_CERT_SIGNER_NOT_FOUND
)
443 printf ("- Peer's certificate issuer is unknown\n");
444 if (status
& GNUTLS_CERT_SIGNER_NOT_CA
)
445 printf ("- Peer's certificate issuer is not a CA\n");
446 if (status
& GNUTLS_CERT_INSECURE_ALGORITHM
)
448 ("- Peer's certificate chain uses insecure algorithm\n");
449 if (status
& GNUTLS_CERT_NOT_ACTIVATED
)
451 ("- Peer's certificate chain uses not yet valid certificate\n");
452 if (status
& GNUTLS_CERT_EXPIRED
)
454 ("- Peer's certificate chain uses expired certificate\n");
455 if (status
& GNUTLS_CERT_INVALID
)
456 printf ("- Peer's certificate is NOT trusted\n");
458 printf ("- Peer's certificate is trusted\n");
460 rc
= verify_x509_hostname (session
, hostname
);
461 if (rc
== 0) status
|= GNUTLS_CERT_INVALID
;
463 else if (type
== GNUTLS_CRT_OPENPGP
)
465 if (status
& GNUTLS_CERT_INVALID
)
466 printf ("- Peer's key is invalid\n");
468 printf ("- Peer's key is valid\n");
469 if (status
& GNUTLS_CERT_SIGNER_NOT_FOUND
)
470 printf ("- Could not find a signer of the peer's key\n");
472 rc
= verify_openpgp_hostname (session
, hostname
);
473 if (rc
== 0) status
|= GNUTLS_CERT_INVALID
;
477 fprintf(stderr
, "Unknown certificate type\n");
478 status
|= GNUTLS_CERT_INVALID
;
488 print_dh_info (gnutls_session_t session
, const char *str
, int print
)
490 printf ("- %sDiffie-Hellman parameters\n", str
);
491 printf (" - Using prime: %d bits\n",
492 gnutls_dh_get_prime_bits (session
));
493 printf (" - Secret key: %d bits\n",
494 gnutls_dh_get_secret_bits (session
));
495 printf (" - Peer's public key: %d bits\n",
496 gnutls_dh_get_peers_public_bits (session
));
501 gnutls_datum_t raw_gen
= { NULL
, 0 };
502 gnutls_datum_t raw_prime
= { NULL
, 0 };
503 gnutls_dh_params_t dh_params
= NULL
;
504 unsigned char *params_data
= NULL
;
505 size_t params_data_size
= 0;
507 ret
= gnutls_dh_get_group (session
, &raw_gen
, &raw_prime
);
510 fprintf (stderr
, "gnutls_dh_get_group %d\n", ret
);
514 ret
= gnutls_dh_params_init (&dh_params
);
517 fprintf (stderr
, "gnutls_dh_params_init %d\n", ret
);
522 gnutls_dh_params_import_raw (dh_params
, &raw_prime
,
526 fprintf (stderr
, "gnutls_dh_params_import_raw %d\n", ret
);
530 ret
= gnutls_dh_params_export_pkcs3 (dh_params
,
534 if (ret
!= GNUTLS_E_SHORT_MEMORY_BUFFER
)
536 fprintf (stderr
, "gnutls_dh_params_export_pkcs3 %d\n",
541 params_data
= gnutls_malloc (params_data_size
);
544 fprintf (stderr
, "gnutls_malloc %d\n", ret
);
548 ret
= gnutls_dh_params_export_pkcs3 (dh_params
,
554 fprintf (stderr
, "gnutls_dh_params_export_pkcs3-2 %d\n",
559 printf (" - PKCS#3 format:\n\n%.*s\n", (int) params_data_size
,
563 gnutls_free (params_data
);
564 gnutls_free (raw_prime
.data
);
565 gnutls_free (raw_gen
.data
);
566 gnutls_dh_params_deinit (dh_params
);
571 print_ecdh_info (gnutls_session_t session
, const char *str
)
575 printf ("- %sEC Diffie-Hellman parameters\n", str
);
577 curve
= gnutls_ecc_curve_get (session
);
579 printf (" - Using curve: %s\n", gnutls_ecc_curve_get_name (curve
));
580 printf (" - Curve size: %d bits\n",
581 gnutls_ecc_curve_get_size (curve
) * 8);
586 print_info (gnutls_session_t session
, int print_cert
, int verbose
)
589 gnutls_credentials_type_t cred
;
590 gnutls_kx_algorithm_t kx
;
591 unsigned char session_id
[33];
592 size_t session_id_size
= sizeof (session_id
);
594 /* print session ID */
595 gnutls_session_get_id (session
, session_id
, &session_id_size
);
596 printf ("- Session ID: %s\n",
597 raw_to_string (session_id
, session_id_size
));
599 /* print the key exchange's algorithm name
601 kx
= gnutls_kx_get (session
);
603 cred
= gnutls_auth_get_type (session
);
607 case GNUTLS_CRD_ANON
:
608 if (kx
== GNUTLS_KX_ANON_ECDH
)
609 print_ecdh_info (session
, "Anonymous ");
611 print_dh_info (session
, "Anonymous ", verbose
);
616 /* This should be only called in server
619 if (gnutls_srp_server_get_username (session
) != NULL
)
620 printf ("- SRP authentication. Connected as '%s'\n",
621 gnutls_srp_server_get_username (session
));
626 /* This returns NULL in server side.
628 if (gnutls_psk_client_get_hint (session
) != NULL
)
629 printf ("- PSK authentication. PSK hint '%s'\n",
630 gnutls_psk_client_get_hint (session
));
631 /* This returns NULL in client side.
633 if (gnutls_psk_server_get_username (session
) != NULL
)
634 printf ("- PSK authentication. Connected as '%s'\n",
635 gnutls_psk_server_get_username (session
));
636 if (kx
== GNUTLS_KX_DHE_PSK
)
637 print_dh_info (session
, "Ephemeral ", verbose
);
638 if (kx
== GNUTLS_KX_ECDHE_PSK
)
639 print_ecdh_info (session
, "Ephemeral ");
643 printf ("- TLS/IA authentication\n");
645 case GNUTLS_CRD_CERTIFICATE
:
648 size_t dns_size
= sizeof (dns
);
651 /* This fails in client side */
652 if (gnutls_server_name_get
653 (session
, dns
, &dns_size
, &type
, 0) == 0)
655 printf ("- Given server name[%d]: %s\n", type
, dns
);
659 print_cert_info (session
, verbose
, print_cert
);
661 if (kx
== GNUTLS_KX_DHE_RSA
|| kx
== GNUTLS_KX_DHE_DSS
)
662 print_dh_info (session
, "Ephemeral ", verbose
);
663 else if (kx
== GNUTLS_KX_ECDHE_RSA
664 || kx
== GNUTLS_KX_ECDHE_ECDSA
)
665 print_ecdh_info (session
, "Ephemeral ");
669 SU (gnutls_protocol_get_name
670 (gnutls_protocol_get_version (session
)));
671 printf ("- Version: %s\n", tmp
);
673 tmp
= SU (gnutls_kx_get_name (kx
));
674 printf ("- Key Exchange: %s\n", tmp
);
676 tmp
= SU (gnutls_cipher_get_name (gnutls_cipher_get (session
)));
677 printf ("- Cipher: %s\n", tmp
);
679 tmp
= SU (gnutls_mac_get_name (gnutls_mac_get (session
)));
680 printf ("- MAC: %s\n", tmp
);
683 SU (gnutls_compression_get_name
684 (gnutls_compression_get (session
)));
685 printf ("- Compression: %s\n", tmp
);
692 rc
= gnutls_session_channel_binding (session
,
693 GNUTLS_CB_TLS_UNIQUE
, &cb
);
695 fprintf (stderr
, "Channel binding error: %s\n",
696 gnutls_strerror (rc
));
701 printf ("- Channel binding 'tls-unique': ");
702 for (i
= 0; i
< cb
.size
; i
++)
703 printf ("%02x", cb
.data
[i
]);
708 /* Warning: Do not print anything more here. The 'Compression:'
709 output MUST be the last non-verbose output. This is used by
710 Emacs starttls.el code. */
718 print_cert_info (gnutls_session_t session
, int verbose
, int print_cert
)
722 if (verbose
) flag
= GNUTLS_CRT_PRINT_FULL
;
723 else flag
= GNUTLS_CRT_PRINT_COMPACT
;
725 if (gnutls_certificate_client_get_request_status (session
) != 0)
726 printf ("- Server has requested a certificate.\n");
728 switch (gnutls_certificate_type_get (session
))
730 case GNUTLS_CRT_X509
:
731 print_x509_info (session
, flag
, print_cert
);
733 #ifdef ENABLE_OPENPGP
734 case GNUTLS_CRT_OPENPGP
:
735 print_openpgp_info (session
, flag
, print_cert
);
739 printf ("Unknown type\n");
745 print_cert_info_compact (gnutls_session_t session
)
748 if (gnutls_certificate_client_get_request_status (session
) != 0)
749 printf ("- Server has requested a certificate.\n");
751 switch (gnutls_certificate_type_get (session
))
753 case GNUTLS_CRT_X509
:
754 print_x509_info_compact (session
);
756 #ifdef ENABLE_OPENPGP
757 case GNUTLS_CRT_OPENPGP
:
758 print_openpgp_info_compact (session
);
762 printf ("Unknown type\n");
768 print_list (const char *priorities
, int verbose
)
776 gnutls_kx_algorithm_t kx
;
777 gnutls_cipher_algorithm_t cipher
;
778 gnutls_mac_algorithm_t mac
;
779 gnutls_protocol_t version
;
780 gnutls_priority_t pcache
;
781 const unsigned int *list
;
783 if (priorities
!= NULL
)
785 printf ("Cipher suites for %s\n", priorities
);
787 ret
= gnutls_priority_init (&pcache
, priorities
, &err
);
790 fprintf (stderr
, "Syntax error at: %s\n", err
);
797 gnutls_priority_get_cipher_suite_index (pcache
, i
,
799 if (ret
== GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
)
801 if (ret
== GNUTLS_E_UNKNOWN_CIPHER_SUITE
)
805 gnutls_cipher_suite_info (idx
, id
, NULL
, NULL
, NULL
,
809 printf ("%-50s\t0x%02x, 0x%02x\t%s\n",
810 name
, (unsigned char) id
[0],
811 (unsigned char) id
[1],
812 gnutls_protocol_get_name (version
));
817 ret
= gnutls_priority_certificate_type_list (pcache
, &list
);
819 printf ("Certificate types: ");
820 if (ret
== 0) printf("none\n");
821 for (i
= 0; i
< (unsigned)ret
; i
++)
824 gnutls_certificate_type_get_name (list
[i
]));
825 if (i
+1!=(unsigned)ret
)
833 ret
= gnutls_priority_protocol_list (pcache
, &list
);
835 printf ("Protocols: ");
836 if (ret
== 0) printf("none\n");
837 for (i
= 0; i
< (unsigned)ret
; i
++)
839 printf ("VERS-%s", gnutls_protocol_get_name (list
[i
]));
840 if (i
+1!=(unsigned)ret
)
848 ret
= gnutls_priority_compression_list (pcache
, &list
);
850 printf ("Compression: ");
851 if (ret
== 0) printf("none\n");
852 for (i
= 0; i
< (unsigned)ret
; i
++)
855 gnutls_compression_get_name (list
[i
]));
856 if (i
+1!=(unsigned)ret
)
864 ret
= gnutls_priority_ecc_curve_list (pcache
, &list
);
866 printf ("Elliptic curves: ");
867 if (ret
== 0) printf("none\n");
868 for (i
= 0; i
< (unsigned)ret
; i
++)
871 gnutls_ecc_curve_get_name (list
[i
]));
872 if (i
+1!=(unsigned)ret
)
880 ret
= gnutls_priority_sign_list (pcache
, &list
);
882 printf ("PK-signatures: ");
883 if (ret
== 0) printf("none\n");
884 for (i
= 0; i
< (unsigned)ret
; i
++)
887 gnutls_sign_algorithm_get_name (list
[i
]));
888 if (i
+1!=(unsigned)ret
)
898 printf ("Cipher suites:\n");
899 for (i
= 0; (name
= gnutls_cipher_suite_info
900 (i
, id
, &kx
, &cipher
, &mac
, &version
)); i
++)
902 printf ("%-50s\t0x%02x, 0x%02x\t%s\n",
904 (unsigned char) id
[0], (unsigned char) id
[1],
905 gnutls_protocol_get_name (version
));
907 printf ("\tKey exchange: %s\n\tCipher: %s\n\tMAC: %s\n\n",
908 gnutls_kx_get_name (kx
),
909 gnutls_cipher_get_name (cipher
),
910 gnutls_mac_get_name (mac
));
915 const gnutls_certificate_type_t
*p
=
916 gnutls_certificate_type_list ();
918 printf ("Certificate types: ");
921 printf ("CTYPE-%s", gnutls_certificate_type_get_name (*p
));
930 const gnutls_protocol_t
*p
= gnutls_protocol_list ();
932 printf ("Protocols: ");
935 printf ("VERS-%s", gnutls_protocol_get_name (*p
));
944 const gnutls_cipher_algorithm_t
*p
= gnutls_cipher_list ();
946 printf ("Ciphers: ");
949 printf ("%s", gnutls_cipher_get_name (*p
));
958 const gnutls_mac_algorithm_t
*p
= gnutls_mac_list ();
963 printf ("%s", gnutls_mac_get_name (*p
));
972 const gnutls_kx_algorithm_t
*p
= gnutls_kx_list ();
974 printf ("Key exchange algorithms: ");
977 printf ("%s", gnutls_kx_get_name (*p
));
986 const gnutls_compression_method_t
*p
= gnutls_compression_list ();
988 printf ("Compression: ");
991 printf ("COMP-%s", gnutls_compression_get_name (*p
));
1000 const gnutls_ecc_curve_t
*p
= gnutls_ecc_curve_list ();
1002 printf ("Elliptic curves: ");
1005 printf ("CURVE-%s", gnutls_ecc_curve_get_name (*p
));
1014 const gnutls_pk_algorithm_t
*p
= gnutls_pk_list ();
1016 printf ("Public Key Systems: ");
1019 printf ("%s", gnutls_pk_algorithm_get_name (*p
));
1028 const gnutls_sign_algorithm_t
*p
= gnutls_sign_list ();
1030 printf ("PK-signatures: ");
1033 printf ("SIGN-%s", gnutls_sign_algorithm_get_name (*p
));
1042 int check_command(gnutls_session_t session
, const char* str
)
1044 size_t len
= strnlen(str
, 128);
1047 fprintf (stderr
, "*** Processing %zu bytes command: %s\n", len
, str
);
1048 if (len
> 2 && str
[0] == str
[1] && str
[0] == '*')
1050 if (strncmp(str
, "**REHANDSHAKE**", sizeof ("**REHANDSHAKE**") - 1) == 0)
1052 fprintf (stderr
, "*** Sending rehandshake request\n");
1053 gnutls_rehandshake (session
);
1055 } else if (strncmp(str
, "**HEARTBEAT**", sizeof ("**HEARTBEAT**") - 1) == 0) {
1056 ret
= gnutls_heartbeat_ping (session
, 300, 5, GNUTLS_HEARTBEAT_WAIT
);
1059 if (ret
== GNUTLS_E_INVALID_REQUEST
)
1061 fprintf(stderr
, "No heartbeat in this session\n");
1065 fprintf(stderr
, "ping: %s\n", gnutls_strerror(ret
));
1075 #define MIN(x,y) ((x)<(y))?(x):(y)
1076 #define MAX_CACHE_TRIES 5
1078 pin_callback (void *user
, int attempt
, const char *token_url
,
1079 const char *token_label
, unsigned int flags
, char *pin
,
1082 const char *password
;
1084 int len
, cache
= MAX_CACHE_TRIES
;
1085 /* allow caching of PIN */
1086 static char *cached_url
= NULL
;
1087 static char cached_pin
[32] = "";
1089 if (flags
& GNUTLS_PIN_SO
)
1090 desc
= "security officer";
1094 if (flags
& GNUTLS_PIN_FINAL_TRY
)
1097 printf ("*** This is the final try before locking!\n");
1099 if (flags
& GNUTLS_PIN_COUNT_LOW
)
1102 printf ("*** Only few tries left before locking!\n");
1105 if (flags
& GNUTLS_PIN_WRONG
)
1108 printf ("*** Wrong PIN has been provided!\n");
1111 if (cache
> 0 && cached_url
!= NULL
)
1113 if (strcmp (cached_url
, token_url
) == 0)
1115 if (strlen(pin
) >= sizeof(cached_pin
))
1117 fprintf (stderr
, "Too long PIN given\n");
1121 fprintf(stderr
, "Re-using cached PIN for token '%s'\n", token_label
);
1122 strcpy (pin
, cached_pin
);
1128 printf ("Token '%s' with URL '%s' ", token_label
, token_url
);
1129 printf ("requires %s PIN\n", desc
);
1131 password
= getpass ("Enter PIN: ");
1132 if (password
== NULL
|| password
[0] == 0)
1134 fprintf (stderr
, "No password given\n");
1138 len
= MIN (pin_max
, strlen (password
));
1139 memcpy (pin
, password
, len
);
1143 strcpy (cached_pin
, pin
);
1145 cached_url
= strdup (token_url
);
1146 cache
= MAX_CACHE_TRIES
;
1151 #ifdef ENABLE_PKCS11
1154 token_callback (void *user
, const char *label
, const unsigned retry
)
1160 fprintf (stderr
, "Could not find token %s\n", label
);
1163 printf ("Please insert token '%s' in slot and press enter\n", label
);
1164 fgets (buf
, sizeof (buf
), stdin
);
1170 pkcs11_common (void)
1173 gnutls_pkcs11_set_pin_function (pin_callback
, NULL
);
1174 gnutls_pkcs11_set_token_function (token_callback
, NULL
);