2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
3 * 2009, 2010 Free Software Foundation, Inc.
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/>.
26 #include <sys/types.h>
30 #include <sys/socket.h>
31 #include <sys/select.h>
36 #include <gnutls/gnutls.h>
37 #include <gnutls/extra.h>
38 #include <gnutls/x509.h>
39 #include <gnutls/openpgp.h>
40 #include <gnutls/pkcs11.h>
42 /* Gnulib portability files. */
44 #include <version-etc.h>
45 #include <read-file.h>
55 /* global stuff here */
56 int resume
, starttls
, insecure
, rehandshake
;
57 const char *hostname
= NULL
;
63 extern int print_cert
;
65 char *srp_passwd
= NULL
;
73 char *x509_crlfile
= NULL
;
75 static int disable_extensions
;
77 char *psk_username
= NULL
;
78 gnutls_datum_t psk_key
= { NULL
, 0 };
80 static gnutls_srp_client_credentials_t srp_cred
;
81 static gnutls_psk_client_credentials_t psk_cred
;
82 static gnutls_anon_client_credentials_t anon_cred
;
83 static gnutls_certificate_credentials_t xcred
;
87 /* end of global stuff */
93 gnutls_session_t session
;
99 struct addrinfo
*addr_info
;
102 ssize_t
socket_recv (const socket_st
* socket
, void *buffer
, int buffer_size
);
103 ssize_t
socket_send (const socket_st
* socket
, const void *buffer
,
105 void socket_open (socket_st
* hd
, const char *hostname
, const char *service
);
106 void socket_connect (const socket_st
* hd
);
107 void socket_bye (socket_st
* socket
);
109 static void check_rehandshake (socket_st
* socket
, int ret
);
110 static int do_handshake (socket_st
* socket
);
111 static void init_global_tls_stuff (void);
113 /* Helper functions to load a certificate and key
116 static gnutls_datum_t
117 load_file (const char *file
)
119 gnutls_datum_t loaded_file
= { NULL
, 0 };
122 loaded_file
.data
= read_binary_file (file
, &length
);
123 if (loaded_file
.data
)
124 loaded_file
.size
= (unsigned int) length
;
130 unload_file (gnutls_datum_t data
)
136 static unsigned int x509_crt_size
;
137 static gnutls_x509_crt_t x509_crt
[MAX_CRT
];
138 static gnutls_x509_privkey_t x509_key
= NULL
;
140 static gnutls_pkcs11_privkey_t pkcs11_key
= NULL
;
142 static gnutls_openpgp_crt_t pgp_crt
= NULL
;
143 static gnutls_openpgp_privkey_t pgp_key
= NULL
;
146 get_keyid (gnutls_openpgp_keyid_t keyid
, const char *str
)
148 size_t keyid_size
= sizeof (keyid
);
150 if (strlen (str
) != 16)
153 "The OpenPGP subkey ID has to be 16 hexadecimal characters.\n");
157 if (gnutls_hex2bin (str
, strlen (str
), keyid
, &keyid_size
) < 0)
159 fprintf (stderr
, "Error converting hex string: %s.\n", str
);
166 /* Load the certificate and the private key.
171 unsigned int crt_num
;
173 gnutls_datum_t data
= { NULL
, 0 };
175 if (x509_certfile
!= NULL
&& x509_keyfile
!= NULL
)
178 if (strncmp (x509_certfile
, "pkcs11:", 7) == 0)
181 gnutls_x509_crt_init (&x509_crt
[0]);
184 gnutls_x509_crt_import_pkcs11_url (x509_crt
[0], x509_certfile
, 0);
186 if (ret
== GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
)
188 gnutls_x509_crt_import_pkcs11_url (x509_crt
[0], x509_certfile
,
189 GNUTLS_PKCS11_OBJ_FLAG_LOGIN
);
193 fprintf (stderr
, "*** Error loading cert file.\n");
199 #endif /* ENABLE_PKCS11 */
202 data
= load_file (x509_certfile
);
203 if (data
.data
== NULL
)
205 fprintf (stderr
, "*** Error loading cert file.\n");
211 gnutls_x509_crt_list_import (x509_crt
, &crt_num
, &data
,
213 GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED
);
216 if (ret
== GNUTLS_E_SHORT_MEMORY_BUFFER
)
219 "*** Error loading cert file: Too many certs %d\n",
226 "*** Error loading cert file: %s\n",
227 gnutls_strerror (ret
));
233 fprintf (stderr
, "Processed %d client certificates...\n", ret
);
238 if (strncmp (x509_keyfile
, "pkcs11:", 7) == 0)
240 gnutls_pkcs11_privkey_init (&pkcs11_key
);
243 gnutls_pkcs11_privkey_import_url (pkcs11_key
, x509_keyfile
, 0);
246 fprintf (stderr
, "*** Error loading url: %s\n",
247 gnutls_strerror (ret
));
252 #endif /* ENABLE_PKCS11 */
254 data
= load_file (x509_keyfile
);
255 if (data
.data
== NULL
)
257 fprintf (stderr
, "*** Error loading key file.\n");
261 gnutls_x509_privkey_init (&x509_key
);
264 gnutls_x509_privkey_import (x509_key
, &data
, GNUTLS_X509_FMT_PEM
);
267 fprintf (stderr
, "*** Error loading key file: %s\n",
268 gnutls_strerror (ret
));
275 fprintf (stderr
, "Processed %d client X.509 certificates...\n",
278 #ifdef ENABLE_OPENPGP
279 if (pgp_certfile
!= NULL
&& pgp_keyfile
!= NULL
)
281 data
= load_file (pgp_certfile
);
282 if (data
.data
== NULL
)
284 fprintf (stderr
, "*** Error loading PGP cert file.\n");
287 gnutls_openpgp_crt_init (&pgp_crt
);
290 gnutls_openpgp_crt_import (pgp_crt
, &data
, GNUTLS_OPENPGP_FMT_BASE64
);
294 "*** Error loading PGP cert file: %s\n",
295 gnutls_strerror (ret
));
303 if (strncmp (pgp_keyfile
, "pkcs11:", 7) == 0)
305 gnutls_pkcs11_privkey_init (&pkcs11_key
);
307 ret
= gnutls_pkcs11_privkey_import_url (pkcs11_key
, pgp_keyfile
, 0);
310 fprintf (stderr
, "*** Error loading url: %s\n",
311 gnutls_strerror (ret
));
316 #endif /* ENABLE_PKCS11 */
319 data
= load_file (pgp_keyfile
);
320 if (data
.data
== NULL
)
322 fprintf (stderr
, "*** Error loading PGP key file.\n");
326 gnutls_openpgp_privkey_init (&pgp_key
);
329 gnutls_openpgp_privkey_import (pgp_key
, &data
,
330 GNUTLS_OPENPGP_FMT_BASE64
, NULL
,
335 "*** Error loading PGP key file: %s\n",
336 gnutls_strerror (ret
));
343 if (info
.pgp_subkey
!= NULL
)
345 unsigned char keyid
[GNUTLS_OPENPGP_KEYID_SIZE
];
347 if (strcasecmp (info
.pgp_subkey
, "auto") == 0)
349 ret
= gnutls_openpgp_crt_get_auth_subkey (pgp_crt
, keyid
, 1);
353 "*** Error setting preferred sub key id (%s): %s\n",
354 info
.pgp_subkey
, gnutls_strerror (ret
));
359 get_keyid (keyid
, info
.pgp_subkey
);
361 ret
= gnutls_openpgp_crt_set_preferred_key_id (pgp_crt
, keyid
);
364 gnutls_openpgp_privkey_set_preferred_key_id (pgp_key
, keyid
);
368 "*** Error setting preferred sub key id (%s): %s\n",
369 info
.pgp_subkey
, gnutls_strerror (ret
));
374 fprintf (stderr
, "Processed 1 client PGP certificate...\n");
381 cert_verify_callback (gnutls_session_t session
)
386 if (!x509_cafile
&& !pgp_keyring
)
389 rc
= gnutls_certificate_verify_peers2 (session
, &status
);
390 if (rc
!= 0 || status
!= 0)
392 printf ("*** Verifying server certificate failed...\n");
400 /* This callback should be associated with a session by calling
401 * gnutls_certificate_client_set_retrieve_function( session, cert_callback),
402 * before a handshake.
406 cert_callback (gnutls_session_t session
,
407 const gnutls_datum_t
* req_ca_rdn
, int nreqs
,
408 const gnutls_pk_algorithm_t
* sign_algos
,
409 int sign_algos_length
, gnutls_retr2_st
* st
)
417 /* Print the server's trusted CAs
420 printf ("- Server's trusted authorities:\n");
422 printf ("- Server did not send us any trusted authorities names.\n");
424 /* print the names (if any) */
425 for (i
= 0; i
< nreqs
; i
++)
427 len
= sizeof (issuer_dn
);
428 ret
= gnutls_x509_rdn_get (&req_ca_rdn
[i
], issuer_dn
, &len
);
431 printf (" [%d]: ", i
);
432 printf ("%s\n", issuer_dn
);
437 /* Select a certificate and return it.
438 * The certificate must be of any of the "sign algorithms"
439 * supported by the server.
442 st
->cert_type
= gnutls_certificate_type_get (session
);
446 if (st
->cert_type
== GNUTLS_CRT_X509
)
448 gnutls_sign_algorithm_t cert_algo
, req_algo
;
451 if (x509_crt_size
> 0)
453 ret
= gnutls_x509_crt_get_signature_algorithm (x509_crt
[0]);
456 /* error reading signature algorithm */
465 gnutls_sign_algorithm_get_requested (session
, i
, &req_algo
);
466 if (ret
>= 0 && cert_algo
== req_algo
)
472 /* server has not requested anything specific */
473 if (i
== 0 && ret
== GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
)
485 ("- Could not find a suitable certificate to send to server\n");
489 if (x509_key
!= NULL
)
491 st
->key
.x509
= x509_key
;
492 st
->key_type
= GNUTLS_PRIVKEY_X509
;
494 else if (pkcs11_key
!= NULL
)
496 st
->key
.pkcs11
= pkcs11_key
;
497 st
->key_type
= GNUTLS_PRIVKEY_PKCS11
;
501 printf ("- Could not find a suitable key to send to server\n");
505 st
->ncerts
= x509_crt_size
;
507 st
->cert
.x509
= x509_crt
;
515 else if (st
->cert_type
== GNUTLS_CRT_OPENPGP
)
522 st
->key
.pgp
= pgp_key
;
523 st
->key_type
= GNUTLS_PRIVKEY_OPENPGP
;
525 else if (pkcs11_key
!= NULL
)
527 st
->key
.pkcs11
= pkcs11_key
;
528 st
->key_type
= GNUTLS_PRIVKEY_PKCS11
;
532 printf ("- Could not find a suitable key to send to server\n");
538 st
->cert
.pgp
= pgp_crt
;
546 printf ("- Successfully sent %d certificate(s) to server.\n", st
->ncerts
);
551 /* initializes a gnutls_session_t with some defaults.
553 static gnutls_session_t
554 init_tls_session (const char *hostname
)
558 gnutls_session_t session
;
560 gnutls_init (&session
, GNUTLS_CLIENT
);
562 if (gnutls_priority_set_direct (session
, info
.priorities
, &err
) < 0)
564 fprintf (stderr
, "Syntax error at: %s\n", err
);
568 /* allow the use of private ciphersuites.
570 if (disable_extensions
== 0)
572 gnutls_handshake_set_private_extensions (session
, 1);
573 gnutls_server_name_set (session
, GNUTLS_NAME_DNS
, hostname
,
577 gnutls_dh_set_prime_bits (session
, 512);
579 gnutls_credentials_set (session
, GNUTLS_CRD_ANON
, anon_cred
);
581 gnutls_credentials_set (session
, GNUTLS_CRD_SRP
, srp_cred
);
583 gnutls_credentials_set (session
, GNUTLS_CRD_PSK
, psk_cred
);
584 gnutls_credentials_set (session
, GNUTLS_CRD_CERTIFICATE
, xcred
);
586 gnutls_certificate_set_retrieve_function (xcred
, cert_callback
);
587 gnutls_certificate_set_verify_function (xcred
, cert_verify_callback
);
588 gnutls_certificate_set_verify_flags (xcred
, 0);
590 /* send the fingerprint */
591 #ifdef ENABLE_OPENPGP
592 if (fingerprint
!= 0)
593 gnutls_openpgp_send_cert (session
, GNUTLS_OPENPGP_CERT_FINGERPRINT
);
596 /* use the max record size extension */
597 if (record_max_size
> 0 && disable_extensions
== 0)
599 if (gnutls_record_set_max_size (session
, record_max_size
) < 0)
602 "Cannot set the maximum record size to %d.\n",
604 fprintf (stderr
, "Possible values: 512, 1024, 2048, 4096.\n");
609 #ifdef ENABLE_SESSION_TICKET
610 if (disable_extensions
== 0 && !info
.noticket
)
611 gnutls_session_ticket_enable_client (session
);
617 static void gaa_parser (int argc
, char **argv
);
619 /* Returns zero if the error code was successfully handled.
622 handle_error (socket_st
* hd
, int err
)
625 const char *err_type
, *str
;
630 if (gnutls_error_is_fatal (err
) == 0)
633 err_type
= "Non fatal";
641 str
= gnutls_strerror (err
);
644 fprintf (stderr
, "*** %s error: %s\n", err_type
, str
);
646 if (err
== GNUTLS_E_WARNING_ALERT_RECEIVED
647 || err
== GNUTLS_E_FATAL_ALERT_RECEIVED
)
649 alert
= gnutls_alert_get (hd
->session
);
650 str
= gnutls_alert_get_name (alert
);
653 printf ("*** Received alert [%d]: %s\n", alert
, str
);
655 /* In SRP if the alert is MISSING_SRP_USERNAME,
656 * we should read the username/password and
657 * call gnutls_handshake(). This is not implemented
662 check_rehandshake (hd
, err
);
667 int starttls_alarmed
= 0;
671 starttls_alarm (int signum
)
673 starttls_alarmed
= 1;
678 tls_log_func (int level
, const char *str
)
680 fprintf (stderr
, "|<%d>| %s", level
, str
);
683 #define IN_KEYBOARD 1
686 /* returns IN_KEYBOARD for keyboard input and IN_NET for network input
688 static int check_net_or_keyboard_input(socket_st
* hd
)
698 FD_SET (fileno (stdin
), &rset
);
699 FD_SET (hd
->fd
, &rset
);
701 maxfd
= MAX (fileno (stdin
), hd
->fd
);
703 tv
.tv_usec
= 500 * 1000;
706 if (gnutls_record_check_pending(hd
->session
))
709 err
= select (maxfd
+ 1, &rset
, NULL
, NULL
, &tv
);
713 if (FD_ISSET (hd
->fd
, &rset
))
717 if (FD_ISSET (fileno (stdin
), &rset
))
726 main (int argc
, char **argv
)
730 char buffer
[MAX_BUF
+ 1];
731 char *session_data
= NULL
;
732 char *session_id
= NULL
;
733 size_t session_data_size
;
734 size_t session_id_size
= 0;
735 int user_term
= 0, retval
= 0;
739 set_program_name (argv
[0]);
741 if ((ret
= gnutls_global_init ()) < 0)
743 fprintf (stderr
, "global_init: %s\n", gnutls_strerror (ret
));
747 if ((ret
= gnutls_global_init_extra ()) < 0)
749 fprintf (stderr
, "global_init_extra: %s\n", gnutls_strerror (ret
));
756 gaa_parser (argc
, argv
);
757 if (hostname
== NULL
)
759 fprintf (stderr
, "No hostname given\n");
763 gnutls_global_set_log_function (tls_log_func
);
764 gnutls_global_set_log_level (info
.debug
);
769 signal (SIGPIPE
, SIG_IGN
);
772 init_global_tls_stuff ();
774 socket_open (&hd
, hostname
, service
);
775 socket_connect (&hd
);
777 hd
.session
= init_tls_session (hostname
);
779 goto after_handshake
;
781 for (i
= 0; i
< 2; i
++)
787 hd
.session
= init_tls_session (hostname
);
788 gnutls_session_set_data (hd
.session
, session_data
,
793 ret
= do_handshake (&hd
);
797 fprintf (stderr
, "*** Handshake has failed\n");
799 gnutls_deinit (hd
.session
);
804 printf ("- Handshake was completed\n");
805 if (gnutls_session_is_resumed (hd
.session
) != 0)
806 printf ("*** This is a resumed session\n");
809 if (resume
!= 0 && i
== 0)
812 gnutls_session_get_data (hd
.session
, NULL
, &session_data_size
);
813 session_data
= malloc (session_data_size
);
815 gnutls_session_get_data (hd
.session
, session_data
,
818 gnutls_session_get_id (hd
.session
, NULL
, &session_id_size
);
820 session_id
= malloc (session_id_size
);
821 gnutls_session_get_id (hd
.session
, session_id
, &session_id_size
);
823 /* print some information */
824 print_info (hd
.session
, hostname
, info
.insecure
);
826 printf ("- Disconnecting\n");
830 ("\n\n- Connecting again- trying to resume previous session\n");
831 socket_open (&hd
, hostname
, service
);
832 socket_connect (&hd
);
842 /* Warning! Do not touch this text string, it is used by external
843 programs to search for when gnutls-cli has reached this point. */
844 printf ("\n- Simple Client Mode:\n\n");
848 ret
= do_handshake (&hd
);
852 fprintf (stderr
, "*** ReHandshake has failed\n");
854 gnutls_deinit (hd
.session
);
859 printf ("- ReHandshake was completed\n");
864 signal (SIGALRM
, &starttls_alarm
);
871 #if !(defined _WIN32 || defined __WIN32__)
872 setbuf (stdin
, NULL
);
874 setbuf (stdout
, NULL
);
875 setbuf (stderr
, NULL
);
879 if (starttls_alarmed
&& !hd
.secure
)
881 /* Warning! Do not touch this text string, it is used by
882 external programs to search for when gnutls-cli has
883 reached this point. */
884 fprintf (stderr
, "*** Starting TLS handshake\n");
885 ret
= do_handshake (&hd
);
888 fprintf (stderr
, "*** Handshake has failed\n");
895 inp
= check_net_or_keyboard_input(&hd
);
899 memset (buffer
, 0, MAX_BUF
+ 1);
900 ret
= socket_recv (&hd
, buffer
, MAX_BUF
);
904 printf ("- Peer has closed the GnuTLS connection\n");
907 else if (handle_error (&hd
, ret
) < 0 && user_term
== 0)
910 "*** Server has terminated the connection abnormally.\n");
917 printf ("- Received[%d]: ", ret
);
918 for (ii
= 0; ii
< ret
; ii
++)
920 fputc (buffer
[ii
], stdout
);
929 if (inp
== IN_KEYBOARD
)
931 if ((bytes
= read (fileno (stdin
), buffer
, MAX_BUF
- 1)) <= 0)
935 /* Warning! Do not touch this text string, it is
936 used by external programs to search for when
937 gnutls-cli has reached this point. */
938 fprintf (stderr
, "*** Starting TLS handshake\n");
939 ret
= do_handshake (&hd
);
943 fprintf (stderr
, "*** Handshake has failed\n");
960 char *b
= strchr (buffer
, '\n');
968 ret
= socket_send (&hd
, buffer
, bytes
);
973 printf ("- Sent: %d bytes\n", ret
);
976 handle_error (&hd
, ret
);
984 gnutls_deinit (hd
.session
);
988 gnutls_srp_free_client_credentials (srp_cred
);
992 gnutls_psk_free_client_credentials (psk_cred
);
995 gnutls_certificate_free_credentials (xcred
);
998 gnutls_anon_free_client_credentials (anon_cred
);
1001 gnutls_global_deinit ();
1007 gaa_parser (int argc
, char **argv
)
1009 if (gaa (argc
, argv
, &info
) != -1)
1012 "Error in the arguments. Use the --help or -h parameters to get more information.\n");
1016 verbose
= info
.verbose
;
1017 disable_extensions
= info
.disable_extensions
;
1018 print_cert
= info
.print_cert
;
1019 starttls
= info
.starttls
;
1020 resume
= info
.resume
;
1021 rehandshake
= info
.rehandshake
;
1022 insecure
= info
.insecure
;
1023 service
= info
.port
;
1024 record_max_size
= info
.record_size
;
1025 fingerprint
= info
.fingerprint
;
1027 if (info
.fmtder
== 0)
1028 x509ctype
= GNUTLS_X509_FMT_PEM
;
1030 x509ctype
= GNUTLS_X509_FMT_DER
;
1032 srp_username
= info
.srp_username
;
1033 srp_passwd
= info
.srp_passwd
;
1034 x509_cafile
= info
.x509_cafile
;
1035 x509_crlfile
= info
.x509_crlfile
;
1036 x509_keyfile
= info
.x509_keyfile
;
1037 x509_certfile
= info
.x509_certfile
;
1038 pgp_keyfile
= info
.pgp_keyfile
;
1039 pgp_certfile
= info
.pgp_certfile
;
1041 psk_username
= info
.psk_username
;
1042 psk_key
.data
= (unsigned char *) info
.psk_key
;
1043 if (info
.psk_key
!= NULL
)
1044 psk_key
.size
= strlen (info
.psk_key
);
1048 pgp_keyring
= info
.pgp_keyring
;
1052 if (info
.rest_args
== NULL
)
1053 hostname
= "localhost";
1055 hostname
= info
.rest_args
;
1058 void cli_version (void);
1063 const char *p
= PACKAGE_NAME
;
1064 if (strcmp (gnutls_check_version (NULL
), PACKAGE_VERSION
) != 0)
1066 version_etc (stdout
, program_name
, p
, gnutls_check_version (NULL
),
1067 "Nikos Mavrogiannopoulos", (char *) NULL
);
1072 check_rehandshake (socket_st
* socket
, int ret
)
1074 if (socket
->secure
&& ret
== GNUTLS_E_REHANDSHAKE
)
1076 /* There is a race condition here. If application
1077 * data is sent after the rehandshake request,
1078 * the server thinks we ignored his request.
1079 * This is a bad design of this client.
1081 printf ("*** Received rehandshake request\n");
1082 /* gnutls_alert_send( session, GNUTLS_AL_WARNING, GNUTLS_A_NO_RENEGOTIATION); */
1084 ret
= do_handshake (socket
);
1088 printf ("*** Rehandshake was performed.\n");
1092 printf ("*** Rehandshake Failed.\n");
1099 do_handshake (socket_st
* socket
)
1103 gnutls_transport_set_ptr (socket
->session
,
1104 (gnutls_transport_ptr_t
)
1105 gl_fd_to_handle (socket
->fd
));
1108 ret
= gnutls_handshake (socket
->session
);
1112 handle_error (socket
, ret
);
1115 while (ret
< 0 && gnutls_error_is_fatal (ret
) == 0);
1119 /* print some information */
1120 print_info (socket
->session
, socket
->hostname
, info
.insecure
);
1128 gnutls_alert_send_appropriate (socket
->session
, ret
);
1129 shutdown (socket
->fd
, SHUT_RDWR
);
1135 srp_username_callback (gnutls_session_t session
,
1136 char **username
, char **password
)
1138 if (srp_username
== NULL
|| srp_passwd
== NULL
)
1143 *username
= gnutls_strdup (srp_username
);
1144 *password
= gnutls_strdup (srp_passwd
);
1150 psk_callback (gnutls_session_t session
, char **username
, gnutls_datum_t
* key
)
1152 const char *hint
= gnutls_psk_client_get_hint (session
);
1153 unsigned char *rawkey
;
1159 printf ("- PSK client callback. ");
1161 printf ("PSK hint '%s'\n", hint
);
1163 printf ("No PSK hint\n");
1165 if (info
.psk_username
)
1166 *username
= gnutls_strdup (info
.psk_username
);
1172 printf ("Enter PSK identity: ");
1174 getline (&tmp
, &n
, stdin
);
1178 fprintf (stderr
, "No username given, aborting...\n");
1179 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
1182 if (tmp
[strlen (tmp
) - 1] == '\n')
1183 tmp
[strlen (tmp
) - 1] = '\0';
1184 if (tmp
[strlen (tmp
) - 1] == '\r')
1185 tmp
[strlen (tmp
) - 1] = '\0';
1187 *username
= gnutls_strdup (tmp
);
1191 return GNUTLS_E_MEMORY_ERROR
;
1193 passwd
= getpass ("Enter key: ");
1196 fprintf (stderr
, "No key given, aborting...\n");
1197 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
1201 tmp
.size
= strlen (passwd
);
1203 res_size
= tmp
.size
/ 2 + 1;
1204 rawkey
= gnutls_malloc (res_size
);
1206 return GNUTLS_E_MEMORY_ERROR
;
1208 ret
= gnutls_hex_decode (&tmp
, rawkey
, &res_size
);
1211 fprintf (stderr
, "Error deriving password: %s\n",
1212 gnutls_strerror (ret
));
1213 gnutls_free (*username
);
1218 key
->size
= res_size
;
1223 res_size
= sizeof (hexkey
);
1224 gnutls_hex_encode (key
, hexkey
, &res_size
);
1225 fprintf (stderr
, "PSK username: %s\n", *username
);
1226 fprintf (stderr
, "PSK hint: %s\n", hint
);
1227 fprintf (stderr
, "PSK key: %s\n", hexkey
);
1234 init_global_tls_stuff (void)
1239 if (gnutls_certificate_allocate_credentials (&xcred
) < 0)
1241 fprintf (stderr
, "Certificate allocation memory error\n");
1245 if (x509_cafile
!= NULL
)
1247 ret
= gnutls_certificate_set_x509_trust_file (xcred
,
1248 x509_cafile
, x509ctype
);
1251 fprintf (stderr
, "Error setting the x509 trust file\n");
1255 printf ("Processed %d CA certificate(s).\n", ret
);
1259 if (x509_crlfile
!= NULL
)
1261 ret
= gnutls_certificate_set_x509_crl_file (xcred
, x509_crlfile
,
1265 fprintf (stderr
, "Error setting the x509 CRL file\n");
1269 printf ("Processed %d CRL(s).\n", ret
);
1276 #ifdef ENABLE_OPENPGP
1277 if (pgp_keyring
!= NULL
)
1280 gnutls_certificate_set_openpgp_keyring_file (xcred
, pgp_keyring
,
1281 GNUTLS_OPENPGP_FMT_BASE64
);
1284 fprintf (stderr
, "Error setting the OpenPGP keyring file\n");
1290 if (srp_username
&& srp_passwd
)
1293 if (gnutls_srp_allocate_client_credentials (&srp_cred
) < 0)
1295 fprintf (stderr
, "SRP authentication error\n");
1298 gnutls_srp_set_client_credentials_function (srp_cred
,
1299 srp_username_callback
);
1305 if (gnutls_psk_allocate_client_credentials (&psk_cred
) < 0)
1307 fprintf (stderr
, "PSK authentication error\n");
1310 if (psk_username
&& psk_key
.data
)
1312 ret
= gnutls_psk_set_client_credentials (psk_cred
,
1313 psk_username
, &psk_key
,
1314 GNUTLS_PSK_KEY_HEX
);
1317 fprintf (stderr
, "Error setting the PSK credentials: %s\n",
1318 gnutls_strerror (ret
));
1321 gnutls_psk_set_client_credentials_function (psk_cred
, psk_callback
);
1326 if (gnutls_anon_allocate_client_credentials (&anon_cred
) < 0)
1328 fprintf (stderr
, "Anonymous authentication error\n");
1334 /* Functions to manipulate sockets
1338 socket_recv (const socket_st
* socket
, void *buffer
, int buffer_size
)
1345 ret
= gnutls_record_recv (socket
->session
, buffer
, buffer_size
);
1347 while (ret
== GNUTLS_E_INTERRUPTED
|| ret
== GNUTLS_E_AGAIN
);
1351 ret
= recv (socket
->fd
, buffer
, buffer_size
, 0);
1353 while (ret
== -1 && errno
== EINTR
);
1359 socket_send (const socket_st
* socket
, const void *buffer
, int buffer_size
)
1366 ret
= gnutls_record_send (socket
->session
, buffer
, buffer_size
);
1368 while (ret
== GNUTLS_E_AGAIN
|| ret
== GNUTLS_E_INTERRUPTED
);
1372 ret
= send (socket
->fd
, buffer
, buffer_size
, 0);
1374 while (ret
== -1 && errno
== EINTR
);
1376 if (ret
> 0 && ret
!= buffer_size
&& verbose
)
1378 "*** Only sent %d bytes instead of %d.\n", ret
, buffer_size
);
1384 socket_bye (socket_st
* socket
)
1390 ret
= gnutls_bye (socket
->session
, GNUTLS_SHUT_WR
);
1391 while (ret
== GNUTLS_E_INTERRUPTED
|| ret
== GNUTLS_E_AGAIN
);
1393 fprintf (stderr
, "*** gnutls_bye() error: %s\n",
1394 gnutls_strerror (ret
));
1395 gnutls_deinit (socket
->session
);
1396 socket
->session
= NULL
;
1399 freeaddrinfo (socket
->addr_info
);
1400 socket
->addr_info
= socket
->ptr
= NULL
;
1403 free (socket
->hostname
);
1404 free (socket
->service
);
1406 shutdown (socket
->fd
, SHUT_RDWR
); /* no more receptions */
1414 socket_connect (const socket_st
* hd
)
1418 printf ("Connecting to '%s:%s'...\n", hd
->ip
, hd
->service
);
1420 err
= connect (hd
->fd
, hd
->ptr
->ai_addr
, hd
->ptr
->ai_addrlen
);
1423 fprintf (stderr
, "Cannot connect to %s:%s: %s\n", hd
->hostname
,
1424 hd
->service
, strerror (errno
));
1430 socket_open (socket_st
* hd
, const char *hostname
, const char *service
)
1432 struct addrinfo hints
, *res
, *ptr
;
1434 char buffer
[MAX_BUF
+ 1];
1435 char portname
[16] = { 0 };
1437 printf ("Resolving '%s'...\n", hostname
);
1438 /* get server name */
1439 memset (&hints
, 0, sizeof (hints
));
1440 hints
.ai_socktype
= SOCK_STREAM
;
1441 if ((err
= getaddrinfo (hostname
, service
, &hints
, &res
)))
1443 fprintf (stderr
, "Cannot resolve %s:%s: %s\n", hostname
, service
,
1444 gai_strerror (err
));
1449 for (ptr
= res
; ptr
!= NULL
; ptr
= ptr
->ai_next
)
1451 sd
= socket (ptr
->ai_family
, ptr
->ai_socktype
, ptr
->ai_protocol
);
1455 if ((err
= getnameinfo (ptr
->ai_addr
, ptr
->ai_addrlen
, buffer
, MAX_BUF
,
1456 portname
, sizeof (portname
),
1457 NI_NUMERICHOST
| NI_NUMERICSERV
)) != 0)
1459 fprintf (stderr
, "getnameinfo(): %s\n", gai_strerror (err
));
1469 fprintf (stderr
, "socket(): %s\n", strerror (errno
));
1475 hd
->hostname
= strdup (hostname
);
1476 hd
->ip
= strdup (buffer
);
1477 hd
->service
= strdup (portname
);
1479 hd
->addr_info
= res
;