Add.
[gnutls.git] / src / cli.c
blobd2b54577a295f53a1a7b960a93ef2c2a624a81f6
1 /*
2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation
3 * Copyright (C) 2000,2001,2002,2003 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 #include <stdio.h>
24 #include <errno.h>
25 #include <stdlib.h>
26 #include <sys/types.h>
27 #include <string.h>
28 #include <sys/time.h>
29 #include <sys/stat.h>
30 #include <sys/socket.h>
31 #include <sys/select.h>
32 #include <unistd.h>
33 #include <fcntl.h>
34 #include <error.h>
36 #include <gnutls/gnutls.h>
37 #include <gnutls/extra.h>
38 #include <gnutls/x509.h>
39 #include <gnutls/openpgp.h>
40 #include <gcrypt.h>
42 /* Gnulib portability files. */
43 #include <progname.h>
44 #include <version-etc.h>
45 #include <read-file.h>
46 #include <getpass.h>
47 #include <minmax.h>
48 #include "sockets.h"
50 #include "common.h"
51 #include "cli-gaa.h"
53 #define MAX_BUF 4096
55 /* global stuff here */
56 int resume, starttls, insecure;
57 const char *hostname = NULL;
58 char *service;
59 int record_max_size;
60 int fingerprint;
61 int crlf;
62 int verbose = 0;
63 extern int print_cert;
65 char *srp_passwd = NULL;
66 char *srp_username;
67 char *pgp_keyfile;
68 char *pgp_certfile;
69 char *pgp_keyring;
70 char *x509_keyfile;
71 char *x509_certfile;
72 char *x509_cafile;
73 char *x509_crlfile = NULL;
74 static int x509ctype;
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;
85 static gaainfo info;
87 static int protocol_priority[PRI_MAX];
88 static int kx_priority[PRI_MAX];
89 static int cipher_priority[PRI_MAX];
90 static int comp_priority[PRI_MAX];
91 static int mac_priority[PRI_MAX];
92 static int cert_type_priority[PRI_MAX];
94 /* end of global stuff */
96 /* prototypes */
97 typedef struct
99 int fd;
100 gnutls_session_t session;
101 int secure;
102 char *hostname;
103 char *ip;
104 char *service;
105 struct addrinfo *ptr;
106 struct addrinfo *addr_info;
107 } socket_st;
109 ssize_t socket_recv (const socket_st * socket, void *buffer, int buffer_size);
110 ssize_t socket_send (const socket_st * socket, const void *buffer,
111 int buffer_size);
112 void socket_open (socket_st * hd, const char *hostname, const char *service);
113 void socket_connect (const socket_st * hd);
114 void socket_bye (socket_st * socket);
116 static void check_rehandshake (socket_st * socket, int ret);
117 static int do_handshake (socket_st * socket);
118 static void init_global_tls_stuff (void);
120 /* Helper functions to load a certificate and key
121 * files into memory.
123 static gnutls_datum_t
124 load_file (const char *file)
126 gnutls_datum_t loaded_file = { NULL, 0 };
127 size_t length;
129 loaded_file.data = read_binary_file (file, &length);
130 if (loaded_file.data)
131 loaded_file.size = (unsigned int) length;
133 return loaded_file;
136 static void
137 unload_file (gnutls_datum_t data)
139 free (data.data);
142 #define MAX_CRT 6
143 static unsigned int x509_crt_size;
144 static gnutls_x509_crt_t x509_crt[MAX_CRT];
145 static gnutls_x509_privkey_t x509_key = NULL;
147 static gnutls_openpgp_crt_t pgp_crt = NULL;
148 static gnutls_openpgp_privkey_t pgp_key = NULL;
150 static void
151 get_keyid (gnutls_openpgp_keyid_t keyid, const char *str)
153 size_t keyid_size = sizeof (keyid);
155 if (strlen (str) != 16)
157 fprintf (stderr,
158 "The OpenPGP subkey ID has to be 16 hexadecimal characters.\n");
159 exit (1);
162 if (gnutls_hex2bin (str, strlen (str), keyid, &keyid_size) < 0)
164 fprintf (stderr, "Error converting hex string: %s.\n", str);
165 exit (1);
168 return;
171 /* Load the certificate and the private key.
173 static void
174 load_keys (void)
176 unsigned int crt_num;
177 int ret;
178 gnutls_datum_t data;
180 if (x509_certfile != NULL && x509_keyfile != NULL)
182 data = load_file (x509_certfile);
183 if (data.data == NULL)
185 fprintf (stderr, "*** Error loading cert file.\n");
186 exit (1);
189 crt_num = MAX_CRT;
190 ret =
191 gnutls_x509_crt_list_import (x509_crt, &crt_num, &data,
192 GNUTLS_X509_FMT_PEM,
193 GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
194 if (ret < 0)
196 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
198 fprintf (stderr,
199 "*** Error loading cert file: Too many certs %d\n",
200 crt_num);
203 else
205 fprintf (stderr,
206 "*** Error loading cert file: %s\n",
207 gnutls_strerror (ret));
209 exit (1);
211 x509_crt_size = ret;
212 fprintf (stderr, "Processed %d client certificates...\n", ret);
214 unload_file (data);
216 data = load_file (x509_keyfile);
217 if (data.data == NULL)
219 fprintf (stderr, "*** Error loading key file.\n");
220 exit (1);
223 gnutls_x509_privkey_init (&x509_key);
225 ret = gnutls_x509_privkey_import (x509_key, &data, GNUTLS_X509_FMT_PEM);
226 if (ret < 0)
228 fprintf (stderr, "*** Error loading key file: %s\n",
229 gnutls_strerror (ret));
230 exit (1);
233 unload_file (data);
235 fprintf (stderr, "Processed %d client X.509 certificates...\n",
236 x509_crt_size);
238 #ifdef ENABLE_OPENPGP
239 if (pgp_certfile != NULL && pgp_keyfile != NULL)
241 data = load_file (pgp_certfile);
242 if (data.data == NULL)
244 fprintf (stderr, "*** Error loading PGP cert file.\n");
245 exit (1);
247 gnutls_openpgp_crt_init (&pgp_crt);
249 ret =
250 gnutls_openpgp_crt_import (pgp_crt, &data, GNUTLS_OPENPGP_FMT_BASE64);
251 if (ret < 0)
253 fprintf (stderr,
254 "*** Error loading PGP cert file: %s\n",
255 gnutls_strerror (ret));
256 exit (1);
260 unload_file (data);
262 data = load_file (pgp_keyfile);
263 if (data.data == NULL)
265 fprintf (stderr, "*** Error loading PGP key file.\n");
266 exit (1);
269 gnutls_openpgp_privkey_init (&pgp_key);
271 ret =
272 gnutls_openpgp_privkey_import (pgp_key, &data,
273 GNUTLS_OPENPGP_FMT_BASE64, NULL, 0);
274 if (ret < 0)
276 fprintf (stderr,
277 "*** Error loading PGP key file: %s\n",
278 gnutls_strerror (ret));
279 exit (1);
282 unload_file (data);
284 if (info.pgp_subkey != NULL)
286 gnutls_openpgp_keyid_t keyid;
288 if (strcasecmp (info.pgp_subkey, "auto") == 0)
290 ret = gnutls_openpgp_crt_get_auth_subkey (pgp_crt, keyid, 1);
291 if (ret < 0)
293 fprintf (stderr,
294 "*** Error setting preferred sub key id (%s): %s\n",
295 info.pgp_subkey, gnutls_strerror (ret));
296 exit (1);
299 else
300 get_keyid (keyid, info.pgp_subkey);
302 ret = gnutls_openpgp_crt_set_preferred_key_id (pgp_crt, keyid);
303 if (ret >= 0)
304 ret =
305 gnutls_openpgp_privkey_set_preferred_key_id (pgp_key, keyid);
306 if (ret < 0)
308 fprintf (stderr,
309 "*** Error setting preferred sub key id (%s): %s\n",
310 info.pgp_subkey, gnutls_strerror (ret));
311 exit (1);
315 fprintf (stderr, "Processed 1 client PGP certificate...\n");
317 #endif
323 /* This callback should be associated with a session by calling
324 * gnutls_certificate_client_set_retrieve_function( session, cert_callback),
325 * before a handshake.
328 static int
329 cert_callback (gnutls_session_t session,
330 const gnutls_datum_t * req_ca_rdn, int nreqs,
331 const gnutls_pk_algorithm_t * sign_algos,
332 int sign_algos_length, gnutls_retr_st * st)
334 char issuer_dn[256];
335 int i, ret;
336 size_t len;
338 if (verbose)
341 /* Print the server's trusted CAs
343 if (nreqs > 0)
344 printf ("- Server's trusted authorities:\n");
345 else
346 printf ("- Server did not send us any trusted authorities names.\n");
348 /* print the names (if any) */
349 for (i = 0; i < nreqs; i++)
351 len = sizeof (issuer_dn);
352 ret = gnutls_x509_rdn_get (&req_ca_rdn[i], issuer_dn, &len);
353 if (ret >= 0)
355 printf (" [%d]: ", i);
356 printf ("%s\n", issuer_dn);
361 /* Select a certificate and return it.
362 * The certificate must be of any of the "sign algorithms"
363 * supported by the server.
366 st->type = gnutls_certificate_type_get (session);
368 st->ncerts = 0;
370 if (st->type == GNUTLS_CRT_X509)
372 if (x509_crt != NULL && x509_key != NULL)
374 st->ncerts = x509_crt_size;
376 st->cert.x509 = x509_crt;
377 st->key.x509 = x509_key;
379 st->deinit_all = 0;
381 return 0;
384 else if (st->type == GNUTLS_CRT_OPENPGP)
386 if (pgp_key != NULL && pgp_crt != NULL)
388 st->ncerts = 1;
390 st->cert.pgp = pgp_crt;
391 st->key.pgp = pgp_key;
393 st->deinit_all = 0;
395 return 0;
399 printf ("- Successfully sent %d certificate(s) to server.\n", st->ncerts);
400 return 0;
404 /* initializes a gnutls_session_t with some defaults.
406 static gnutls_session_t
407 init_tls_session (const char *hostname)
409 const char *err;
411 gnutls_session_t session;
413 gnutls_init (&session, GNUTLS_CLIENT);
415 if (gnutls_priority_set_direct (session, info.priorities, &err) < 0)
417 fprintf (stderr, "Syntax error at: %s\n", err);
418 exit (1);
421 /* allow the use of private ciphersuites.
423 if (disable_extensions == 0)
425 gnutls_handshake_set_private_extensions (session, 1);
426 gnutls_server_name_set (session, GNUTLS_NAME_DNS, hostname,
427 strlen (hostname));
428 if (cert_type_priority[0])
429 gnutls_certificate_type_set_priority (session, cert_type_priority);
432 if (cipher_priority[0])
433 gnutls_cipher_set_priority (session, cipher_priority);
434 if (comp_priority[0])
435 gnutls_compression_set_priority (session, comp_priority);
436 if (kx_priority[0])
437 gnutls_kx_set_priority (session, kx_priority);
438 if (protocol_priority[0])
439 gnutls_protocol_set_priority (session, protocol_priority);
440 if (mac_priority[0])
441 gnutls_mac_set_priority (session, mac_priority);
443 gnutls_dh_set_prime_bits (session, 512);
445 gnutls_credentials_set (session, GNUTLS_CRD_ANON, anon_cred);
446 if (srp_cred)
447 gnutls_credentials_set (session, GNUTLS_CRD_SRP, srp_cred);
448 if (psk_cred)
449 gnutls_credentials_set (session, GNUTLS_CRD_PSK, psk_cred);
450 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
452 gnutls_certificate_client_set_retrieve_function (xcred, cert_callback);
454 /* send the fingerprint */
455 #ifdef ENABLE_OPENPGP
456 if (fingerprint != 0)
457 gnutls_openpgp_send_cert (session, GNUTLS_OPENPGP_CERT_FINGERPRINT);
458 #endif
460 /* use the max record size extension */
461 if (record_max_size > 0 && disable_extensions == 0)
463 if (gnutls_record_set_max_size (session, record_max_size) < 0)
465 fprintf (stderr,
466 "Cannot set the maximum record size to %d.\n",
467 record_max_size);
468 fprintf (stderr, "Possible values: 512, 1024, 2048, 4096.\n");
469 exit (1);
473 #ifdef ENABLE_OPRFI
474 if (info.opaque_prf_input)
475 gnutls_oprfi_enable_client (session, strlen (info.opaque_prf_input),
476 info.opaque_prf_input);
477 #endif
479 #ifdef ENABLE_SESSION_TICKET
480 if (!info.noticket)
481 gnutls_session_ticket_enable_client (session);
482 #endif
484 return session;
487 static void gaa_parser (int argc, char **argv);
489 /* Returns zero if the error code was successfully handled.
491 static int
492 handle_error (socket_st * hd, int err)
494 int alert, ret;
495 const char *err_type, *str;
497 if (err >= 0)
498 return 0;
500 if (gnutls_error_is_fatal (err) == 0)
502 ret = 0;
503 err_type = "Non fatal";
505 else
507 ret = err;
508 err_type = "Fatal";
511 str = gnutls_strerror (err);
512 if (str == NULL)
513 str = str_unknown;
514 fprintf (stderr, "*** %s error: %s\n", err_type, str);
516 if (err == GNUTLS_E_WARNING_ALERT_RECEIVED
517 || err == GNUTLS_E_FATAL_ALERT_RECEIVED)
519 alert = gnutls_alert_get (hd->session);
520 str = gnutls_alert_get_name (alert);
521 if (str == NULL)
522 str = str_unknown;
523 printf ("*** Received alert [%d]: %s\n", alert, str);
525 /* In SRP if the alert is MISSING_SRP_USERNAME,
526 * we should read the username/password and
527 * call gnutls_handshake(). This is not implemented
528 * here.
532 check_rehandshake (hd, err);
534 return ret;
537 int starttls_alarmed = 0;
539 static void
540 starttls_alarm (int signum)
542 starttls_alarmed = 1;
545 static void
546 tls_log_func (int level, const char *str)
548 fprintf (stderr, "|<%d>| %s", level, str);
552 main (int argc, char **argv)
554 int err, ret;
555 int ii, i;
556 char buffer[MAX_BUF + 1];
557 char *session_data = NULL;
558 char *session_id = NULL;
559 size_t session_data_size;
560 size_t session_id_size;
561 fd_set rset;
562 int maxfd;
563 struct timeval tv;
564 int user_term = 0, retval = 0;
565 socket_st hd;
567 set_program_name (argv[0]);
569 gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
571 #ifdef gcry_fips_mode_active
572 /* Libgcrypt manual says that gcry_version_check must be called
573 before calling gcry_fips_mode_active. */
574 gcry_check_version (NULL);
575 if (gcry_fips_mode_active ())
577 ret = gnutls_register_md5_handler ();
578 if (ret)
579 fprintf (stderr, "gnutls_register_md5_handler: %s\n",
580 gnutls_strerror (ret));
582 #endif
584 if ((ret = gnutls_global_init ()) < 0)
586 fprintf (stderr, "global_init: %s\n", gnutls_strerror (ret));
587 exit (1);
590 if ((ret = gnutls_global_init_extra ()) < 0)
592 fprintf (stderr, "global_init_extra: %s\n", gnutls_strerror (ret));
593 exit (1);
596 gaa_parser (argc, argv);
597 if (hostname == NULL)
599 fprintf (stderr, "No hostname given\n");
600 exit (1);
603 gnutls_global_set_log_function (tls_log_func);
604 gnutls_global_set_log_level (info.debug);
606 sockets_init ();
608 #ifndef _WIN32
609 signal (SIGPIPE, SIG_IGN);
610 #endif
612 init_global_tls_stuff ();
614 socket_open (&hd, hostname, service);
615 socket_connect (&hd);
617 hd.session = init_tls_session (hostname);
618 if (starttls)
619 goto after_handshake;
621 for (i = 0; i < 2; i++)
625 if (i == 1)
627 hd.session = init_tls_session (hostname);
628 gnutls_session_set_data (hd.session, session_data,
629 session_data_size);
630 free (session_data);
633 ret = do_handshake (&hd);
635 if (ret < 0)
637 fprintf (stderr, "*** Handshake has failed\n");
638 gnutls_perror (ret);
639 gnutls_deinit (hd.session);
640 return 1;
642 else
644 printf ("- Handshake was completed\n");
645 if (gnutls_session_is_resumed (hd.session) != 0)
646 printf ("*** This is a resumed session\n");
649 if (resume != 0 && i == 0)
652 gnutls_session_get_data (hd.session, NULL, &session_data_size);
653 session_data = malloc (session_data_size);
655 gnutls_session_get_data (hd.session, session_data,
656 &session_data_size);
658 gnutls_session_get_id (hd.session, NULL, &session_id_size);
659 session_id = malloc (session_id_size);
660 gnutls_session_get_id (hd.session, session_id, &session_id_size);
662 /* print some information */
663 print_info (hd.session, hostname, info.insecure);
665 printf ("- Disconnecting\n");
666 socket_bye (&hd);
668 printf
669 ("\n\n- Connecting again- trying to resume previous session\n");
670 socket_open (&hd, hostname, service);
671 socket_connect (&hd);
673 else
675 break;
679 after_handshake:
681 /* Warning! Do not touch this text string, it is used by external
682 programs to search for when gnutls-cli has reached this point. */
683 printf ("\n- Simple Client Mode:\n\n");
685 #ifndef _WIN32
686 signal (SIGALRM, &starttls_alarm);
687 #endif
689 /* do not buffer */
690 #if !(defined _WIN32 || defined __WIN32__)
691 setbuf (stdin, NULL);
692 #endif
693 setbuf (stdout, NULL);
694 setbuf (stderr, NULL);
696 for (;;)
698 if (starttls_alarmed && !hd.secure)
700 /* Warning! Do not touch this text string, it is used by
701 external programs to search for when gnutls-cli has
702 reached this point. */
703 fprintf (stderr, "*** Starting TLS handshake\n");
704 ret = do_handshake (&hd);
705 if (ret < 0)
707 fprintf (stderr, "*** Handshake has failed\n");
708 user_term = 1;
709 retval = 1;
710 break;
714 FD_ZERO (&rset);
715 FD_SET (fileno (stdin), &rset);
716 FD_SET (hd.fd, &rset);
718 maxfd = MAX (fileno (stdin), hd.fd);
719 tv.tv_sec = 3;
720 tv.tv_usec = 0;
722 err = select (maxfd + 1, &rset, NULL, NULL, &tv);
723 if (err < 0)
724 continue;
726 if (FD_ISSET (hd.fd, &rset))
728 memset (buffer, 0, MAX_BUF + 1);
729 ret = socket_recv (&hd, buffer, MAX_BUF);
731 if (ret == 0)
733 printf ("- Peer has closed the GNUTLS connection\n");
734 break;
736 else if (handle_error (&hd, ret) < 0 && user_term == 0)
738 fprintf (stderr,
739 "*** Server has terminated the connection abnormally.\n");
740 retval = 1;
741 break;
743 else if (ret > 0)
745 if (verbose != 0)
746 printf ("- Received[%d]: ", ret);
747 for (ii = 0; ii < ret; ii++)
749 fputc (buffer[ii], stdout);
751 fflush (stdout);
754 if (user_term != 0)
755 break;
758 if (FD_ISSET (fileno (stdin), &rset))
760 if (fgets (buffer, MAX_BUF, stdin) == NULL)
762 if (hd.secure == 0)
764 /* Warning! Do not touch this text string, it is
765 used by external programs to search for when
766 gnutls-cli has reached this point. */
767 fprintf (stderr, "*** Starting TLS handshake\n");
768 ret = do_handshake (&hd);
769 clearerr (stdin);
770 if (ret < 0)
772 fprintf (stderr, "*** Handshake has failed\n");
773 user_term = 1;
774 retval = 1;
775 break;
778 else
780 user_term = 1;
781 break;
783 continue;
786 if (crlf != 0)
788 char *b = strchr (buffer, '\n');
789 if (b != NULL)
790 strcpy (b, "\r\n");
793 ret = socket_send (&hd, buffer, strlen (buffer));
795 if (ret > 0)
797 if (verbose != 0)
798 printf ("- Sent: %d bytes\n", ret);
800 else
801 handle_error (&hd, ret);
806 if (info.debug)
807 gcry_control (GCRYCTL_DUMP_RANDOM_STATS);
809 if (user_term != 0)
810 socket_bye (&hd);
811 else
812 gnutls_deinit (hd.session);
814 #ifdef ENABLE_SRP
815 if (srp_cred)
816 gnutls_srp_free_client_credentials (srp_cred);
817 #endif
818 #ifdef ENABLE_PSK
819 if (psk_cred)
820 gnutls_psk_free_client_credentials (psk_cred);
821 #endif
823 gnutls_certificate_free_credentials (xcred);
825 #ifdef ENABLE_ANON
826 gnutls_anon_free_client_credentials (anon_cred);
827 #endif
829 gnutls_global_deinit ();
831 return retval;
834 void
835 gaa_parser (int argc, char **argv)
837 if (gaa (argc, argv, &info) != -1)
839 fprintf (stderr,
840 "Error in the arguments. Use the --help or -h parameters to get more information.\n");
841 exit (1);
844 verbose = info.verbose;
845 disable_extensions = info.disable_extensions;
846 print_cert = info.print_cert;
847 starttls = info.starttls;
848 resume = info.resume;
849 insecure = info.insecure;
850 service = info.port;
851 record_max_size = info.record_size;
852 fingerprint = info.fingerprint;
854 if (info.fmtder == 0)
855 x509ctype = GNUTLS_X509_FMT_PEM;
856 else
857 x509ctype = GNUTLS_X509_FMT_DER;
859 srp_username = info.srp_username;
860 srp_passwd = info.srp_passwd;
861 x509_cafile = info.x509_cafile;
862 x509_crlfile = info.x509_crlfile;
863 x509_keyfile = info.x509_keyfile;
864 x509_certfile = info.x509_certfile;
865 pgp_keyfile = info.pgp_keyfile;
866 pgp_certfile = info.pgp_certfile;
868 psk_username = info.psk_username;
869 psk_key.data = (unsigned char *) info.psk_key;
870 if (info.psk_key != NULL)
871 psk_key.size = strlen (info.psk_key);
872 else
873 psk_key.size = 0;
875 pgp_keyring = info.pgp_keyring;
877 crlf = info.crlf;
879 if (info.rest_args == NULL)
880 hostname = "localhost";
881 else
882 hostname = info.rest_args;
884 parse_protocols (info.proto, info.nproto, protocol_priority);
885 parse_ciphers (info.ciphers, info.nciphers, cipher_priority);
886 parse_macs (info.macs, info.nmacs, mac_priority);
887 parse_ctypes (info.ctype, info.nctype, cert_type_priority);
888 parse_kx (info.kx, info.nkx, kx_priority);
889 parse_comp (info.comp, info.ncomp, comp_priority);
892 void cli_version (void);
894 void
895 cli_version (void)
897 const char *p = PACKAGE_NAME;
898 if (strcmp (gnutls_check_version (NULL), PACKAGE_VERSION) != 0)
899 p = PACKAGE_STRING;
900 version_etc (stdout, program_name, p, gnutls_check_version (NULL),
901 "Nikos Mavrogiannopoulos", (char *) NULL);
905 static void
906 check_rehandshake (socket_st * socket, int ret)
908 if (socket->secure && ret == GNUTLS_E_REHANDSHAKE)
910 /* There is a race condition here. If application
911 * data is sent after the rehandshake request,
912 * the server thinks we ignored his request.
913 * This is a bad design of this client.
915 printf ("*** Received rehandshake request\n");
916 /* gnutls_alert_send( session, GNUTLS_AL_WARNING, GNUTLS_A_NO_RENEGOTIATION); */
918 ret = do_handshake (socket);
920 if (ret == 0)
922 printf ("*** Rehandshake was performed.\n");
924 else
926 printf ("*** Rehandshake Failed.\n");
932 static int
933 do_handshake (socket_st * socket)
935 int ret;
937 gnutls_transport_set_ptr (socket->session,
938 (gnutls_transport_ptr_t)
939 gl_fd_to_handle (socket->fd));
942 ret = gnutls_handshake (socket->session);
944 if (ret < 0)
946 handle_error (socket, ret);
949 while (ret < 0 && gnutls_error_is_fatal (ret) == 0);
951 if (ret == 0)
953 /* print some information */
954 print_info (socket->session, socket->hostname, info.insecure);
956 if ((x509_cafile || pgp_keyring) && !insecure)
958 int rc;
959 unsigned int status;
961 /* abort if verification fail */
962 rc = gnutls_certificate_verify_peers2 (socket->session, &status);
963 if (rc != 0 || status != 0)
965 printf ("*** Verifying server certificate failed...\n");
966 exit (1);
970 socket->secure = 1;
973 return ret;
976 static int
977 srp_username_callback (gnutls_session_t session,
978 char **username, char **password)
980 if (srp_username == NULL || srp_passwd == NULL)
982 return -1;
985 *username = gnutls_strdup (srp_username);
986 *password = gnutls_strdup (srp_passwd);
988 return 0;
991 static int
992 psk_callback (gnutls_session_t session, char **username, gnutls_datum_t * key)
994 const char *hint = gnutls_psk_client_get_hint (session);
995 char *passwd;
996 int ret;
998 printf ("- PSK client callback. ");
999 if (hint)
1000 printf ("PSK hint '%s'\n", hint);
1001 else
1002 printf ("No PSK hint\n");
1004 if (info.psk_username)
1005 *username = gnutls_strdup (info.psk_username);
1006 else
1008 char *tmp = NULL;
1009 size_t n;
1010 ssize_t len;
1012 printf ("Enter PSK identity: ");
1013 fflush (stdout);
1014 len = getline (&tmp, &n, stdin);
1016 if (tmp == NULL)
1018 fprintf (stderr, "No username given, aborting...\n");
1019 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1022 if (tmp[strlen (tmp) - 1] == '\n')
1023 tmp[strlen (tmp) - 1] = '\0';
1024 if (tmp[strlen (tmp) - 1] == '\r')
1025 tmp[strlen (tmp) - 1] = '\0';
1027 *username = gnutls_strdup (tmp);
1028 free (tmp);
1030 if (!*username)
1031 return GNUTLS_E_MEMORY_ERROR;
1033 passwd = getpass ("Enter password: ");
1034 if (passwd == NULL)
1036 fprintf (stderr, "No password given, aborting...\n");
1037 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1040 ret = gnutls_psk_netconf_derive_key (passwd,
1041 *username, hint ? hint : "", key);
1042 if (ret < 0)
1044 fprintf (stderr, "Error deriving password: %s\n",
1045 gnutls_strerror (ret));
1046 gnutls_free (*username);
1047 return ret;
1050 if (info.debug)
1052 char hexkey[41];
1053 size_t res_size = sizeof (hexkey);
1054 gnutls_hex_encode (key, hexkey, &res_size);
1055 fprintf (stderr, "PSK username: %s\n", *username);
1056 fprintf (stderr, "PSK hint: %s\n", hint);
1057 fprintf (stderr, "PSK key: %s\n", hexkey);
1060 return 0;
1063 static void
1064 init_global_tls_stuff (void)
1066 int ret;
1068 /* X509 stuff */
1069 if (gnutls_certificate_allocate_credentials (&xcred) < 0)
1071 fprintf (stderr, "Certificate allocation memory error\n");
1072 exit (1);
1075 if (x509_cafile != NULL)
1077 ret = gnutls_certificate_set_x509_trust_file (xcred,
1078 x509_cafile, x509ctype);
1079 if (ret < 0)
1081 fprintf (stderr, "Error setting the x509 trust file\n");
1083 else
1085 printf ("Processed %d CA certificate(s).\n", ret);
1088 #ifdef ENABLE_PKI
1089 if (x509_crlfile != NULL)
1091 ret = gnutls_certificate_set_x509_crl_file (xcred, x509_crlfile,
1092 x509ctype);
1093 if (ret < 0)
1095 fprintf (stderr, "Error setting the x509 CRL file\n");
1097 else
1099 printf ("Processed %d CRL(s).\n", ret);
1102 #endif
1104 load_keys ();
1106 #ifdef ENABLE_OPENPGP
1107 if (pgp_keyring != NULL)
1109 ret =
1110 gnutls_certificate_set_openpgp_keyring_file (xcred, pgp_keyring,
1111 GNUTLS_OPENPGP_FMT_BASE64);
1112 if (ret < 0)
1114 fprintf (stderr, "Error setting the OpenPGP keyring file\n");
1117 #endif
1119 #ifdef ENABLE_SRP
1120 if (srp_username && srp_passwd)
1122 /* SRP stuff */
1123 if (gnutls_srp_allocate_client_credentials (&srp_cred) < 0)
1125 fprintf (stderr, "SRP authentication error\n");
1128 gnutls_srp_set_client_credentials_function (srp_cred,
1129 srp_username_callback);
1131 #endif
1133 #ifdef ENABLE_PSK
1134 /* PSK stuff */
1135 if (gnutls_psk_allocate_client_credentials (&psk_cred) < 0)
1137 fprintf (stderr, "PSK authentication error\n");
1140 if (psk_username && psk_key.data)
1142 ret = gnutls_psk_set_client_credentials (psk_cred,
1143 psk_username, &psk_key,
1144 GNUTLS_PSK_KEY_HEX);
1145 if (ret < 0)
1147 fprintf (stderr, "Error setting the PSK credentials: %s\n",
1148 gnutls_strerror (ret));
1151 gnutls_psk_set_client_credentials_function (psk_cred, psk_callback);
1152 #endif
1154 #ifdef ENABLE_ANON
1155 /* ANON stuff */
1156 if (gnutls_anon_allocate_client_credentials (&anon_cred) < 0)
1158 fprintf (stderr, "Anonymous authentication error\n");
1160 #endif
1164 /* Functions to manipulate sockets
1167 ssize_t
1168 socket_recv (const socket_st * socket, void *buffer, int buffer_size)
1170 int ret;
1172 if (socket->secure)
1175 ret = gnutls_record_recv (socket->session, buffer, buffer_size);
1177 while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
1178 else
1181 ret = recv (socket->fd, buffer, buffer_size, 0);
1183 while (ret == -1 && errno == EINTR);
1185 return ret;
1188 ssize_t
1189 socket_send (const socket_st * socket, const void *buffer, int buffer_size)
1191 int ret;
1193 if (socket->secure)
1196 ret = gnutls_record_send (socket->session, buffer, buffer_size);
1198 while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED);
1199 else
1202 ret = send (socket->fd, buffer, buffer_size, 0);
1204 while (ret == -1 && errno == EINTR);
1206 if (ret > 0 && ret != buffer_size && verbose)
1207 fprintf (stderr,
1208 "*** Only sent %d bytes instead of %d.\n", ret, buffer_size);
1210 return ret;
1213 void
1214 socket_bye (socket_st * socket)
1216 int ret;
1217 if (socket->secure)
1220 ret = gnutls_bye (socket->session, GNUTLS_SHUT_RDWR);
1221 while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
1222 if (ret < 0)
1223 fprintf (stderr, "*** gnutls_bye() error: %s\n",
1224 gnutls_strerror (ret));
1225 gnutls_deinit (socket->session);
1226 socket->session = NULL;
1229 freeaddrinfo (socket->addr_info);
1230 socket->addr_info = socket->ptr = NULL;
1232 free (socket->ip);
1233 free (socket->hostname);
1234 free (socket->service);
1236 shutdown (socket->fd, SHUT_RDWR); /* no more receptions */
1237 close (socket->fd);
1239 socket->fd = -1;
1240 socket->secure = 0;
1243 void
1244 socket_connect (const socket_st * hd)
1246 int err;
1248 printf ("Connecting to '%s:%s'...\n", hd->ip, hd->service);
1250 err = connect (hd->fd, hd->ptr->ai_addr, hd->ptr->ai_addrlen);
1251 if (err < 0)
1253 fprintf (stderr, "Cannot connect to %s:%s: %s\n", hd->hostname,
1254 hd->service, strerror (errno));
1255 exit (1);
1259 void
1260 socket_open (socket_st * hd, const char *hostname, const char *service)
1262 struct addrinfo hints, *res, *ptr;
1263 int sd, err;
1264 char buffer[MAX_BUF + 1];
1265 char portname[16] = { 0 };
1267 printf ("Resolving '%s'...\n", hostname);
1268 /* get server name */
1269 memset (&hints, 0, sizeof (hints));
1270 hints.ai_socktype = SOCK_STREAM;
1271 if ((err = getaddrinfo (hostname, service, &hints, &res)))
1273 fprintf (stderr, "Cannot resolve %s:%s: %s\n", hostname, service,
1274 gai_strerror (err));
1275 exit (1);
1278 sd = -1;
1279 for (ptr = res; ptr != NULL; ptr = ptr->ai_next)
1281 sd = socket (ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
1282 if (sd == -1)
1283 continue;
1285 if ((err = getnameinfo (ptr->ai_addr, ptr->ai_addrlen, buffer, MAX_BUF,
1286 portname, sizeof (portname),
1287 NI_NUMERICHOST | NI_NUMERICSERV)) != 0)
1289 fprintf (stderr, "getnameinfo(): %s\n", gai_strerror (err));
1290 freeaddrinfo (res);
1291 exit (1);
1294 break;
1297 if (sd == -1)
1299 fprintf (stderr, "socket(): %s\n", strerror (errno));
1300 exit (1);
1303 hd->secure = 0;
1304 hd->fd = sd;
1305 hd->hostname = strdup (hostname);
1306 hd->ip = strdup (buffer);
1307 hd->service = strdup (portname);
1308 hd->ptr = ptr;
1309 hd->addr_info = res;
1311 return;