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>
41 # include <gnutls/pkcs11.h>
44 #define SU(x) (x!=NULL?x:"Unknown")
46 const char str_unknown
[] = "(unknown)";
48 /* Hex encodes the given data.
51 raw_to_string (const unsigned char *raw
, size_t raw_size
)
53 static char buf
[1024];
58 if (raw_size
* 3 + 1 >= sizeof (buf
))
61 for (i
= 0; i
< raw_size
; i
++)
63 sprintf (&(buf
[i
* 3]), "%02X%s", raw
[i
],
64 (i
== raw_size
- 1) ? "" : ":");
66 buf
[sizeof (buf
) - 1] = '\0';
72 print_x509_info_compact (gnutls_session_t session
)
74 gnutls_x509_crt_t crt
;
75 const gnutls_datum_t
*cert_list
;
76 unsigned int cert_list_size
= 0;
80 cert_list
= gnutls_certificate_get_peers (session
, &cert_list_size
);
81 if (cert_list_size
== 0)
83 fprintf (stderr
, "No certificates found!\n");
87 gnutls_x509_crt_init (&crt
);
89 gnutls_x509_crt_import (crt
, &cert_list
[0],
93 fprintf (stderr
, "Decoding error: %s\n",
94 gnutls_strerror (ret
));
99 gnutls_x509_crt_print (crt
, GNUTLS_CRT_PRINT_COMPACT
, &cinfo
);
102 printf ("- X.509 cert: %s\n", cinfo
.data
);
103 gnutls_free (cinfo
.data
);
106 gnutls_x509_crt_deinit (crt
);
110 print_x509_info (gnutls_session_t session
, int flag
, int print_cert
)
112 gnutls_x509_crt_t crt
;
113 const gnutls_datum_t
*cert_list
;
114 unsigned int cert_list_size
= 0, j
;
117 cert_list
= gnutls_certificate_get_peers (session
, &cert_list_size
);
118 if (cert_list_size
== 0)
120 fprintf (stderr
, "No certificates found!\n");
124 printf ("- Certificate type: X.509\n");
125 printf ("- Got a certificate list of %d certificates.\n",
128 for (j
= 0; j
< cert_list_size
; j
++)
130 gnutls_datum_t cinfo
;
132 gnutls_x509_crt_init (&crt
);
134 gnutls_x509_crt_import (crt
, &cert_list
[j
],
135 GNUTLS_X509_FMT_DER
);
138 fprintf (stderr
, "Decoding error: %s\n",
139 gnutls_strerror (ret
));
143 printf ("- Certificate[%d] info:\n - ", j
);
144 if (flag
== GNUTLS_CRT_PRINT_COMPACT
&& j
> 0) flag
= GNUTLS_CRT_PRINT_ONELINE
;
147 gnutls_x509_crt_print (crt
, flag
, &cinfo
);
150 printf ("%s\n", cinfo
.data
);
151 gnutls_free (cinfo
.data
);
160 gnutls_x509_crt_export (crt
, GNUTLS_X509_FMT_PEM
, p
,
162 if (ret
== GNUTLS_E_SHORT_MEMORY_BUFFER
)
167 fprintf (stderr
, "gnutls_malloc\n");
172 gnutls_x509_crt_export (crt
, GNUTLS_X509_FMT_PEM
,
177 fprintf (stderr
, "Encoding error: %s\n",
178 gnutls_strerror (ret
));
182 fputs ("\n", stdout
);
184 fputs ("\n", stdout
);
189 gnutls_x509_crt_deinit (crt
);
193 /* returns true or false, depending on whether the hostname
194 * matches to certificate */
196 verify_x509_hostname (gnutls_session_t session
, const char *hostname
)
198 gnutls_x509_crt_t crt
;
199 const gnutls_datum_t
*cert_list
;
200 unsigned int cert_list_size
= 0;
203 cert_list
= gnutls_certificate_get_peers (session
, &cert_list_size
);
204 if (cert_list_size
== 0)
206 fprintf (stderr
, "No certificates found!\n");
210 gnutls_x509_crt_init (&crt
);
212 gnutls_x509_crt_import (crt
, &cert_list
[0],
213 GNUTLS_X509_FMT_DER
);
216 fprintf (stderr
, "Decoding error: %s\n",
217 gnutls_strerror (ret
));
221 /* Check the hostname of the first certificate if it matches
222 * the name of the host we connected to.
224 if (hostname
!= NULL
)
226 if (gnutls_x509_crt_check_hostname (crt
, hostname
) == 0)
229 ("- The hostname in the certificate does NOT match '%s'\n",
235 printf ("- The hostname in the certificate matches '%s'.\n",
241 gnutls_x509_crt_deinit (crt
);
246 #ifdef ENABLE_OPENPGP
247 /* returns true or false, depending on whether the hostname
248 * matches to certificate */
250 verify_openpgp_hostname (gnutls_session_t session
, const char *hostname
)
252 gnutls_openpgp_crt_t crt
;
253 const gnutls_datum_t
*cert_list
;
254 unsigned int cert_list_size
= 0;
257 cert_list
= gnutls_certificate_get_peers (session
, &cert_list_size
);
258 if (cert_list_size
== 0)
260 fprintf (stderr
, "No certificates found!\n");
264 gnutls_openpgp_crt_init (&crt
);
266 gnutls_openpgp_crt_import (crt
, &cert_list
[0],
267 GNUTLS_OPENPGP_FMT_RAW
);
270 fprintf (stderr
, "Decoding error: %s\n",
271 gnutls_strerror (ret
));
275 /* Check the hostname of the first certificate if it matches
276 * the name of the host we connected to.
278 if (gnutls_openpgp_crt_check_hostname (crt
, hostname
) == 0)
281 ("- The hostname in the certificate does NOT match '%s'\n",
287 printf ("- The hostname in the certificate matches '%s'.\n",
292 gnutls_openpgp_crt_deinit (crt
);
298 print_openpgp_info_compact (gnutls_session_t session
)
301 gnutls_openpgp_crt_t crt
;
302 const gnutls_datum_t
*cert_list
;
303 unsigned int cert_list_size
= 0;
306 cert_list
= gnutls_certificate_get_peers (session
, &cert_list_size
);
308 if (cert_list_size
> 0)
310 gnutls_datum_t cinfo
;
312 gnutls_openpgp_crt_init (&crt
);
313 ret
= gnutls_openpgp_crt_import (crt
, &cert_list
[0],
314 GNUTLS_OPENPGP_FMT_RAW
);
317 fprintf (stderr
, "Decoding error: %s\n",
318 gnutls_strerror (ret
));
323 gnutls_openpgp_crt_print (crt
, GNUTLS_CRT_PRINT_COMPACT
, &cinfo
);
326 printf ("- OpenPGP cert: %s\n", cinfo
.data
);
327 gnutls_free (cinfo
.data
);
330 gnutls_openpgp_crt_deinit (crt
);
335 print_openpgp_info (gnutls_session_t session
, int flag
, int print_cert
)
338 gnutls_openpgp_crt_t crt
;
339 const gnutls_datum_t
*cert_list
;
340 unsigned int cert_list_size
= 0;
343 printf ("- Certificate type: OpenPGP\n");
345 cert_list
= gnutls_certificate_get_peers (session
, &cert_list_size
);
347 if (cert_list_size
> 0)
349 gnutls_datum_t cinfo
;
351 gnutls_openpgp_crt_init (&crt
);
352 ret
= gnutls_openpgp_crt_import (crt
, &cert_list
[0],
353 GNUTLS_OPENPGP_FMT_RAW
);
356 fprintf (stderr
, "Decoding error: %s\n",
357 gnutls_strerror (ret
));
362 gnutls_openpgp_crt_print (crt
, flag
, &cinfo
);
365 printf ("- %s\n", cinfo
.data
);
366 gnutls_free (cinfo
.data
);
375 gnutls_openpgp_crt_export (crt
,
376 GNUTLS_OPENPGP_FMT_BASE64
,
378 if (ret
== GNUTLS_E_SHORT_MEMORY_BUFFER
)
383 fprintf (stderr
, "gnutls_malloc\n");
388 gnutls_openpgp_crt_export (crt
,
389 GNUTLS_OPENPGP_FMT_BASE64
,
394 fprintf (stderr
, "Encoding error: %s\n",
395 gnutls_strerror (ret
));
400 fputs ("\n", stdout
);
405 gnutls_openpgp_crt_deinit (crt
);
411 /* returns false (0) if not verified, or true (1) otherwise
414 cert_verify (gnutls_session_t session
, const char* hostname
)
417 unsigned int status
= 0;
420 rc
= gnutls_certificate_verify_peers2 (session
, &status
);
421 if (rc
== GNUTLS_E_NO_CERTIFICATE_FOUND
)
423 printf ("- Peer did not send any certificate.\n");
429 printf ("- Could not verify certificate (err: %s)\n",
430 gnutls_strerror (rc
));
434 type
= gnutls_certificate_type_get (session
);
435 if (type
== GNUTLS_CRT_X509
)
438 if (status
& GNUTLS_CERT_REVOKED
)
439 printf ("- Peer's certificate chain revoked\n");
440 if (status
& GNUTLS_CERT_SIGNER_NOT_FOUND
)
441 printf ("- Peer's certificate issuer is unknown\n");
442 if (status
& GNUTLS_CERT_SIGNER_NOT_CA
)
443 printf ("- Peer's certificate issuer is not a CA\n");
444 if (status
& GNUTLS_CERT_INSECURE_ALGORITHM
)
446 ("- Peer's certificate chain uses insecure algorithm\n");
447 if (status
& GNUTLS_CERT_NOT_ACTIVATED
)
449 ("- Peer's certificate chain uses not yet valid certificate\n");
450 if (status
& GNUTLS_CERT_EXPIRED
)
452 ("- Peer's certificate chain uses expired certificate\n");
453 if (status
& GNUTLS_CERT_INVALID
)
454 printf ("- Peer's certificate is NOT trusted\n");
456 printf ("- Peer's certificate is trusted\n");
458 rc
= verify_x509_hostname (session
, hostname
);
459 if (rc
== 0) status
|= GNUTLS_CERT_INVALID
;
461 else if (type
== GNUTLS_CRT_OPENPGP
)
463 if (status
& GNUTLS_CERT_INVALID
)
464 printf ("- Peer's key is invalid\n");
466 printf ("- Peer's key is valid\n");
467 if (status
& GNUTLS_CERT_SIGNER_NOT_FOUND
)
468 printf ("- Could not find a signer of the peer's key\n");
470 rc
= verify_openpgp_hostname (session
, hostname
);
471 if (rc
== 0) status
|= GNUTLS_CERT_INVALID
;
475 fprintf(stderr
, "Unknown certificate type\n");
476 status
|= GNUTLS_CERT_INVALID
;
486 print_dh_info (gnutls_session_t session
, const char *str
, int print
)
488 printf ("- %sDiffie-Hellman parameters\n", str
);
489 printf (" - Using prime: %d bits\n",
490 gnutls_dh_get_prime_bits (session
));
491 printf (" - Secret key: %d bits\n",
492 gnutls_dh_get_secret_bits (session
));
493 printf (" - Peer's public key: %d bits\n",
494 gnutls_dh_get_peers_public_bits (session
));
499 gnutls_datum_t raw_gen
= { NULL
, 0 };
500 gnutls_datum_t raw_prime
= { NULL
, 0 };
501 gnutls_dh_params_t dh_params
= NULL
;
502 unsigned char *params_data
= NULL
;
503 size_t params_data_size
= 0;
505 ret
= gnutls_dh_get_group (session
, &raw_gen
, &raw_prime
);
508 fprintf (stderr
, "gnutls_dh_get_group %d\n", ret
);
512 ret
= gnutls_dh_params_init (&dh_params
);
515 fprintf (stderr
, "gnutls_dh_params_init %d\n", ret
);
520 gnutls_dh_params_import_raw (dh_params
, &raw_prime
,
524 fprintf (stderr
, "gnutls_dh_params_import_raw %d\n", ret
);
528 ret
= gnutls_dh_params_export_pkcs3 (dh_params
,
532 if (ret
!= GNUTLS_E_SHORT_MEMORY_BUFFER
)
534 fprintf (stderr
, "gnutls_dh_params_export_pkcs3 %d\n",
539 params_data
= gnutls_malloc (params_data_size
);
542 fprintf (stderr
, "gnutls_malloc %d\n", ret
);
546 ret
= gnutls_dh_params_export_pkcs3 (dh_params
,
552 fprintf (stderr
, "gnutls_dh_params_export_pkcs3-2 %d\n",
557 printf (" - PKCS#3 format:\n\n%.*s\n", (int) params_data_size
,
561 gnutls_free (params_data
);
562 gnutls_free (raw_prime
.data
);
563 gnutls_free (raw_gen
.data
);
564 gnutls_dh_params_deinit (dh_params
);
569 print_ecdh_info (gnutls_session_t session
, const char *str
)
573 printf ("- %sEC Diffie-Hellman parameters\n", str
);
575 curve
= gnutls_ecc_curve_get (session
);
577 printf (" - Using curve: %s\n", gnutls_ecc_curve_get_name (curve
));
578 printf (" - Curve size: %d bits\n",
579 gnutls_ecc_curve_get_size (curve
) * 8);
584 print_info (gnutls_session_t session
, int print_cert
, int verbose
)
587 gnutls_credentials_type_t cred
;
588 gnutls_kx_algorithm_t kx
;
589 unsigned char session_id
[33];
590 size_t session_id_size
= sizeof (session_id
);
592 /* print session ID */
593 gnutls_session_get_id (session
, session_id
, &session_id_size
);
594 printf ("- Session ID: %s\n",
595 raw_to_string (session_id
, session_id_size
));
597 /* print the key exchange's algorithm name
599 kx
= gnutls_kx_get (session
);
601 cred
= gnutls_auth_get_type (session
);
605 case GNUTLS_CRD_ANON
:
606 if (kx
== GNUTLS_KX_ANON_ECDH
)
607 print_ecdh_info (session
, "Anonymous ");
609 print_dh_info (session
, "Anonymous ", verbose
);
614 /* This should be only called in server
617 if (gnutls_srp_server_get_username (session
) != NULL
)
618 printf ("- SRP authentication. Connected as '%s'\n",
619 gnutls_srp_server_get_username (session
));
624 /* This returns NULL in server side.
626 if (gnutls_psk_client_get_hint (session
) != NULL
)
627 printf ("- PSK authentication. PSK hint '%s'\n",
628 gnutls_psk_client_get_hint (session
));
629 /* This returns NULL in client side.
631 if (gnutls_psk_server_get_username (session
) != NULL
)
632 printf ("- PSK authentication. Connected as '%s'\n",
633 gnutls_psk_server_get_username (session
));
634 if (kx
== GNUTLS_KX_DHE_PSK
)
635 print_dh_info (session
, "Ephemeral ", verbose
);
636 if (kx
== GNUTLS_KX_ECDHE_PSK
)
637 print_ecdh_info (session
, "Ephemeral ");
641 printf ("- TLS/IA authentication\n");
643 case GNUTLS_CRD_CERTIFICATE
:
646 size_t dns_size
= sizeof (dns
);
649 /* This fails in client side */
650 if (gnutls_server_name_get
651 (session
, dns
, &dns_size
, &type
, 0) == 0)
653 printf ("- Given server name[%d]: %s\n", type
, dns
);
657 print_cert_info (session
, verbose
, print_cert
);
659 if (kx
== GNUTLS_KX_DHE_RSA
|| kx
== GNUTLS_KX_DHE_DSS
)
660 print_dh_info (session
, "Ephemeral ", verbose
);
661 else if (kx
== GNUTLS_KX_ECDHE_RSA
662 || kx
== GNUTLS_KX_ECDHE_ECDSA
)
663 print_ecdh_info (session
, "Ephemeral ");
667 SU (gnutls_protocol_get_name
668 (gnutls_protocol_get_version (session
)));
669 printf ("- Version: %s\n", tmp
);
671 tmp
= SU (gnutls_kx_get_name (kx
));
672 printf ("- Key Exchange: %s\n", tmp
);
674 tmp
= SU (gnutls_cipher_get_name (gnutls_cipher_get (session
)));
675 printf ("- Cipher: %s\n", tmp
);
677 tmp
= SU (gnutls_mac_get_name (gnutls_mac_get (session
)));
678 printf ("- MAC: %s\n", tmp
);
681 SU (gnutls_compression_get_name
682 (gnutls_compression_get (session
)));
683 printf ("- Compression: %s\n", tmp
);
690 rc
= gnutls_session_channel_binding (session
,
691 GNUTLS_CB_TLS_UNIQUE
, &cb
);
693 fprintf (stderr
, "Channel binding error: %s\n",
694 gnutls_strerror (rc
));
699 printf ("- Channel binding 'tls-unique': ");
700 for (i
= 0; i
< cb
.size
; i
++)
701 printf ("%02x", cb
.data
[i
]);
706 /* Warning: Do not print anything more here. The 'Compression:'
707 output MUST be the last non-verbose output. This is used by
708 Emacs starttls.el code. */
716 print_cert_info (gnutls_session_t session
, int verbose
, int print_cert
)
720 if (verbose
) flag
= GNUTLS_CRT_PRINT_FULL
;
721 else flag
= GNUTLS_CRT_PRINT_COMPACT
;
723 if (gnutls_certificate_client_get_request_status (session
) != 0)
724 printf ("- Server has requested a certificate.\n");
726 switch (gnutls_certificate_type_get (session
))
728 case GNUTLS_CRT_X509
:
729 print_x509_info (session
, flag
, print_cert
);
731 #ifdef ENABLE_OPENPGP
732 case GNUTLS_CRT_OPENPGP
:
733 print_openpgp_info (session
, flag
, print_cert
);
737 printf ("Unknown type\n");
743 print_cert_info_compact (gnutls_session_t session
)
746 if (gnutls_certificate_client_get_request_status (session
) != 0)
747 printf ("- Server has requested a certificate.\n");
749 switch (gnutls_certificate_type_get (session
))
751 case GNUTLS_CRT_X509
:
752 print_x509_info_compact (session
);
754 #ifdef ENABLE_OPENPGP
755 case GNUTLS_CRT_OPENPGP
:
756 print_openpgp_info_compact (session
);
760 printf ("Unknown type\n");
766 print_list (const char *priorities
, int verbose
)
774 gnutls_kx_algorithm_t kx
;
775 gnutls_cipher_algorithm_t cipher
;
776 gnutls_mac_algorithm_t mac
;
777 gnutls_protocol_t version
;
778 gnutls_priority_t pcache
;
779 const unsigned int *list
;
781 if (priorities
!= NULL
)
783 printf ("Cipher suites for %s\n", priorities
);
785 ret
= gnutls_priority_init (&pcache
, priorities
, &err
);
788 fprintf (stderr
, "Syntax error at: %s\n", err
);
795 gnutls_priority_get_cipher_suite_index (pcache
, i
,
797 if (ret
== GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
)
799 if (ret
== GNUTLS_E_UNKNOWN_CIPHER_SUITE
)
803 gnutls_cipher_suite_info (idx
, id
, NULL
, NULL
, NULL
,
807 printf ("%-50s\t0x%02x, 0x%02x\t%s\n",
808 name
, (unsigned char) id
[0],
809 (unsigned char) id
[1],
810 gnutls_protocol_get_name (version
));
815 ret
= gnutls_priority_certificate_type_list (pcache
, &list
);
817 printf ("Certificate types: ");
818 if (ret
== 0) printf("none\n");
819 for (i
= 0; i
< (unsigned)ret
; i
++)
822 gnutls_certificate_type_get_name (list
[i
]));
823 if (i
+1!=(unsigned)ret
)
831 ret
= gnutls_priority_protocol_list (pcache
, &list
);
833 printf ("Protocols: ");
834 if (ret
== 0) printf("none\n");
835 for (i
= 0; i
< (unsigned)ret
; i
++)
837 printf ("VERS-%s", gnutls_protocol_get_name (list
[i
]));
838 if (i
+1!=(unsigned)ret
)
846 ret
= gnutls_priority_compression_list (pcache
, &list
);
848 printf ("Compression: ");
849 if (ret
== 0) printf("none\n");
850 for (i
= 0; i
< (unsigned)ret
; i
++)
853 gnutls_compression_get_name (list
[i
]));
854 if (i
+1!=(unsigned)ret
)
862 ret
= gnutls_priority_ecc_curve_list (pcache
, &list
);
864 printf ("Elliptic curves: ");
865 if (ret
== 0) printf("none\n");
866 for (i
= 0; i
< (unsigned)ret
; i
++)
869 gnutls_ecc_curve_get_name (list
[i
]));
870 if (i
+1!=(unsigned)ret
)
878 ret
= gnutls_priority_sign_list (pcache
, &list
);
880 printf ("PK-signatures: ");
881 if (ret
== 0) printf("none\n");
882 for (i
= 0; i
< (unsigned)ret
; i
++)
885 gnutls_sign_algorithm_get_name (list
[i
]));
886 if (i
+1!=(unsigned)ret
)
896 printf ("Cipher suites:\n");
897 for (i
= 0; (name
= gnutls_cipher_suite_info
898 (i
, id
, &kx
, &cipher
, &mac
, &version
)); i
++)
900 printf ("%-50s\t0x%02x, 0x%02x\t%s\n",
902 (unsigned char) id
[0], (unsigned char) id
[1],
903 gnutls_protocol_get_name (version
));
905 printf ("\tKey exchange: %s\n\tCipher: %s\n\tMAC: %s\n\n",
906 gnutls_kx_get_name (kx
),
907 gnutls_cipher_get_name (cipher
),
908 gnutls_mac_get_name (mac
));
913 const gnutls_certificate_type_t
*p
=
914 gnutls_certificate_type_list ();
916 printf ("Certificate types: ");
919 printf ("CTYPE-%s", gnutls_certificate_type_get_name (*p
));
928 const gnutls_protocol_t
*p
= gnutls_protocol_list ();
930 printf ("Protocols: ");
933 printf ("VERS-%s", gnutls_protocol_get_name (*p
));
942 const gnutls_cipher_algorithm_t
*p
= gnutls_cipher_list ();
944 printf ("Ciphers: ");
947 printf ("%s", gnutls_cipher_get_name (*p
));
956 const gnutls_mac_algorithm_t
*p
= gnutls_mac_list ();
961 printf ("%s", gnutls_mac_get_name (*p
));
970 const gnutls_kx_algorithm_t
*p
= gnutls_kx_list ();
972 printf ("Key exchange algorithms: ");
975 printf ("%s", gnutls_kx_get_name (*p
));
984 const gnutls_compression_method_t
*p
= gnutls_compression_list ();
986 printf ("Compression: ");
989 printf ("COMP-%s", gnutls_compression_get_name (*p
));
998 const gnutls_ecc_curve_t
*p
= gnutls_ecc_curve_list ();
1000 printf ("Elliptic curves: ");
1003 printf ("CURVE-%s", gnutls_ecc_curve_get_name (*p
));
1012 const gnutls_pk_algorithm_t
*p
= gnutls_pk_list ();
1014 printf ("Public Key Systems: ");
1017 printf ("%s", gnutls_pk_algorithm_get_name (*p
));
1026 const gnutls_sign_algorithm_t
*p
= gnutls_sign_list ();
1028 printf ("PK-signatures: ");
1031 printf ("SIGN-%s", gnutls_sign_algorithm_get_name (*p
));
1040 int check_command(gnutls_session_t session
, const char* str
)
1042 int len
= strlen(str
);
1044 if (len
> 2 && str
[0] == str
[1] && str
[0] == '*')
1046 if (strncmp(str
, "**REHANDSHAKE**",
1047 sizeof ("**REHANDSHAKE**") - 1) == 0)
1049 fprintf (stderr
, "*** Sending rehandshake request\n");
1050 gnutls_rehandshake (session
);
1057 #define MIN(x,y) ((x)<(y))?(x):(y)
1058 #define MAX_CACHE_TRIES 5
1060 pin_callback (void *user
, int attempt
, const char *token_url
,
1061 const char *token_label
, unsigned int flags
, char *pin
,
1064 const char *password
;
1066 int len
, cache
= MAX_CACHE_TRIES
;
1067 /* allow caching of PIN */
1068 static char *cached_url
= NULL
;
1069 static char cached_pin
[32] = "";
1071 if (flags
& GNUTLS_PIN_SO
)
1072 desc
= "security officer";
1076 if (flags
& GNUTLS_PIN_FINAL_TRY
)
1079 printf ("*** This is the final try before locking!\n");
1081 if (flags
& GNUTLS_PIN_COUNT_LOW
)
1084 printf ("*** Only few tries left before locking!\n");
1087 if (flags
& GNUTLS_PIN_WRONG
)
1090 printf ("*** Wrong PIN has been provided!\n");
1093 if (cache
> 0 && cached_url
!= NULL
)
1095 if (strcmp (cached_url
, token_url
) == 0)
1097 if (strlen(pin
) >= sizeof(cached_pin
))
1099 fprintf (stderr
, "Too long PIN given\n");
1103 fprintf(stderr
, "Re-using cached PIN for token '%s'\n", token_label
);
1104 strcpy (pin
, cached_pin
);
1110 printf ("Token '%s' with URL '%s' ", token_label
, token_url
);
1111 printf ("requires %s PIN\n", desc
);
1113 password
= getpass ("Enter PIN: ");
1114 if (password
== NULL
|| password
[0] == 0)
1116 fprintf (stderr
, "No password given\n");
1120 len
= MIN (pin_max
, strlen (password
));
1121 memcpy (pin
, password
, len
);
1125 strcpy (cached_pin
, pin
);
1127 cached_url
= strdup (token_url
);
1128 cache
= MAX_CACHE_TRIES
;
1133 #ifdef ENABLE_PKCS11
1136 token_callback (void *user
, const char *label
, const unsigned retry
)
1142 fprintf (stderr
, "Could not find token %s\n", label
);
1145 printf ("Please insert token '%s' in slot and press enter\n", label
);
1146 fgets (buf
, sizeof (buf
), stdin
);
1152 pkcs11_common (void)
1155 gnutls_pkcs11_set_pin_function (pin_callback
, NULL
);
1156 gnutls_pkcs11_set_token_function (token_callback
, NULL
);