provide accurate value to select
[gnutls.git] / src / cli.c
blobccd59d0786927940564890d3b0b5f68145da81a3
1 /*
2 * Copyright (C) 2000-2012 Free Software Foundation, Inc.
4 * This file is part of GnuTLS.
6 * GnuTLS is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * GnuTLS is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include <config.h>
22 #include <stdio.h>
23 #include <errno.h>
24 #include <stdlib.h>
25 #include <sys/types.h>
26 #include <string.h>
27 #include <sys/time.h>
28 #include <sys/stat.h>
29 #if HAVE_SYS_SOCKET_H
30 # include <sys/socket.h>
31 #elif HAVE_WS2TCPIP_H
32 # include <ws2tcpip.h>
33 #endif
34 #include <sys/select.h>
35 #include <unistd.h>
36 #include <stdint.h>
37 #include <fcntl.h>
38 #include <netdb.h>
40 #include <gnutls/gnutls.h>
41 #include <gnutls/abstract.h>
42 #include <gnutls/dtls.h>
43 #include <gnutls/x509.h>
44 #include <gnutls/openpgp.h>
45 #include <gnutls/pkcs11.h>
47 /* Gnulib portability files. */
48 #include <progname.h>
49 #include <version-etc.h>
50 #include <read-file.h>
51 #include <getpass.h>
52 #include <minmax.h>
54 #include "sockets.h"
55 #include "benchmark.h"
57 #include <common.h>
58 #include <socket.h>
60 #include <gettext.h>
61 #include <cli-args.h>
62 #include <ocsptool-common.h>
64 #define MAX_BUF 4096
66 /* global stuff here */
67 int resume, starttls, insecure, rehandshake, udp, mtu;
68 const char *hostname = NULL;
69 const char *service = NULL;
70 int record_max_size;
71 int fingerprint;
72 int crlf;
73 unsigned int verbose = 0;
74 int print_cert;
76 #define DEFAULT_CA_FILE "/etc/ssl/certs/ca-certificates.crt"
78 const char *srp_passwd = NULL;
79 const char *srp_username = NULL;
80 const char *pgp_keyfile = NULL;
81 const char *pgp_certfile = NULL;
82 const char *pgp_keyring = NULL;
83 const char *x509_keyfile = NULL;
84 const char *x509_certfile = NULL;
85 const char *x509_cafile = NULL;
86 const char *x509_crlfile = NULL;
87 static int x509ctype;
88 static int disable_extensions;
89 static const char * priorities = NULL;
91 const char *psk_username = NULL;
92 gnutls_datum_t psk_key = { NULL, 0 };
94 static gnutls_srp_client_credentials_t srp_cred;
95 static gnutls_psk_client_credentials_t psk_cred;
96 static gnutls_anon_client_credentials_t anon_cred;
97 static gnutls_certificate_credentials_t xcred;
99 /* end of global stuff */
101 /* prototypes */
103 static void check_rehandshake (socket_st * socket, int ret);
104 static int do_handshake (socket_st * socket);
105 static void init_global_tls_stuff (void);
106 static int cert_verify_ocsp (gnutls_session_t session);
108 /* Helper functions to load a certificate and key
109 * files into memory.
111 static gnutls_datum_t
112 load_file (const char *file)
114 gnutls_datum_t loaded_file = { NULL, 0 };
115 size_t length;
117 loaded_file.data = (void*)read_binary_file (file, &length);
118 if (loaded_file.data)
119 loaded_file.size = (unsigned int) length;
121 return loaded_file;
124 static void
125 unload_file (gnutls_datum_t* data)
127 free (data->data);
130 #define MAX_CRT 6
131 static unsigned int x509_crt_size;
132 static gnutls_pcert_st x509_crt[MAX_CRT];
133 static gnutls_privkey_t x509_key = NULL;
135 static gnutls_pcert_st pgp_crt;
136 static gnutls_privkey_t pgp_key = NULL;
138 static void
139 get_keyid (gnutls_openpgp_keyid_t keyid, const char *str)
141 size_t keyid_size = sizeof (keyid);
143 if (strlen (str) != 16)
145 fprintf (stderr,
146 "The OpenPGP subkey ID has to be 16 hexadecimal characters.\n");
147 exit (1);
150 if (gnutls_hex2bin (str, strlen (str), keyid, &keyid_size) < 0)
152 fprintf (stderr, "Error converting hex string: %s.\n", str);
153 exit (1);
156 return;
159 /* Load the certificate and the private key.
161 static void
162 load_keys (void)
164 unsigned int crt_num;
165 int ret;
166 unsigned int i;
167 gnutls_datum_t data = { NULL, 0 };
168 gnutls_x509_crt_t crt_list[MAX_CRT];
169 #ifdef ENABLE_PKCS11
170 gnutls_pkcs11_privkey_t pkcs11_key;
171 #endif
172 gnutls_x509_privkey_t tmp_key;
173 unsigned char keyid[GNUTLS_OPENPGP_KEYID_SIZE];
175 if (x509_certfile != NULL && x509_keyfile != NULL)
177 #ifdef ENABLE_PKCS11
178 if (strncmp (x509_certfile, "pkcs11:", 7) == 0)
180 crt_num = 1;
181 gnutls_x509_crt_init (&crt_list[0]);
183 ret =
184 gnutls_x509_crt_import_pkcs11_url (crt_list[0], x509_certfile, 0);
186 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
187 ret =
188 gnutls_x509_crt_import_pkcs11_url (crt_list[0], x509_certfile,
189 GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
191 if (ret < 0)
193 fprintf (stderr, "*** Error loading cert file.\n");
194 exit (1);
196 x509_crt_size = 1;
198 else
199 #endif /* ENABLE_PKCS11 */
202 data = load_file (x509_certfile);
203 if (data.data == NULL)
205 fprintf (stderr, "*** Error loading cert file.\n");
206 exit (1);
209 crt_num = MAX_CRT;
210 ret =
211 gnutls_x509_crt_list_import (crt_list, &crt_num, &data,
212 GNUTLS_X509_FMT_PEM,
213 GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
214 if (ret < 0)
216 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
218 fprintf (stderr,
219 "*** Error loading cert file: Too many certs %d\n",
220 crt_num);
223 else
225 fprintf (stderr,
226 "*** Error loading cert file: %s\n",
227 gnutls_strerror (ret));
229 exit (1);
231 x509_crt_size = ret;
234 for (i=0;i<x509_crt_size;i++)
236 ret = gnutls_pcert_import_x509(&x509_crt[i], crt_list[i], 0);
237 if (ret < 0)
239 fprintf(stderr, "*** Error importing crt to pcert: %s\n",
240 gnutls_strerror(ret));
241 exit(1);
243 gnutls_x509_crt_deinit(crt_list[i]);
246 unload_file (&data);
248 ret = gnutls_privkey_init(&x509_key);
249 if (ret < 0)
251 fprintf (stderr, "*** Error initializing key: %s\n",
252 gnutls_strerror (ret));
253 exit (1);
256 #ifdef ENABLE_PKCS11
257 if (strncmp (x509_keyfile, "pkcs11:", 7) == 0)
259 gnutls_pkcs11_privkey_init (&pkcs11_key);
261 ret =
262 gnutls_pkcs11_privkey_import_url (pkcs11_key, x509_keyfile, 0);
263 if (ret < 0)
265 fprintf (stderr, "*** Error loading url: %s\n",
266 gnutls_strerror (ret));
267 exit (1);
270 ret = gnutls_privkey_import_pkcs11( x509_key, pkcs11_key, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
271 if (ret < 0)
273 fprintf (stderr, "*** Error loading url: %s\n",
274 gnutls_strerror (ret));
275 exit (1);
278 else
279 #endif /* ENABLE_PKCS11 */
281 data = load_file (x509_keyfile);
282 if (data.data == NULL)
284 fprintf (stderr, "*** Error loading key file.\n");
285 exit (1);
288 gnutls_x509_privkey_init (&tmp_key);
290 ret =
291 gnutls_x509_privkey_import (tmp_key, &data, GNUTLS_X509_FMT_PEM);
292 if (ret < 0)
294 fprintf (stderr, "*** Error loading key file: %s\n",
295 gnutls_strerror (ret));
296 exit (1);
299 ret = gnutls_privkey_import_x509( x509_key, tmp_key, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
300 if (ret < 0)
302 fprintf (stderr, "*** Error loading url: %s\n",
303 gnutls_strerror (ret));
304 exit (1);
307 unload_file (&data);
310 fprintf (stdout, "Processed %d client X.509 certificates...\n",
311 x509_crt_size);
315 #ifdef ENABLE_OPENPGP
316 if (HAVE_OPT(PGPSUBKEY))
318 get_keyid (keyid, OPT_ARG(PGPSUBKEY));
321 if (pgp_certfile != NULL && pgp_keyfile != NULL)
323 gnutls_openpgp_crt_t tmp_pgp_crt;
325 data = load_file (pgp_certfile);
326 if (data.data == NULL)
328 fprintf (stderr, "*** Error loading PGP cert file.\n");
329 exit (1);
332 gnutls_openpgp_crt_init (&tmp_pgp_crt);
334 ret =
335 gnutls_pcert_import_openpgp_raw (&pgp_crt, &data, GNUTLS_OPENPGP_FMT_BASE64, HAVE_OPT(PGPSUBKEY)?keyid:NULL, 0);
336 if (ret < 0)
338 fprintf (stderr,
339 "*** Error loading PGP cert file: %s\n",
340 gnutls_strerror (ret));
341 exit (1);
344 unload_file (&data);
346 ret = gnutls_privkey_init(&pgp_key);
347 if (ret < 0)
349 fprintf (stderr, "*** Error initializing key: %s\n",
350 gnutls_strerror (ret));
351 exit (1);
354 #ifdef ENABLE_PKCS11
355 if (strncmp (pgp_keyfile, "pkcs11:", 7) == 0)
357 gnutls_pkcs11_privkey_init (&pkcs11_key);
359 ret = gnutls_pkcs11_privkey_import_url (pkcs11_key, pgp_keyfile, 0);
360 if (ret < 0)
362 fprintf (stderr, "*** Error loading url: %s\n",
363 gnutls_strerror (ret));
364 exit (1);
367 ret = gnutls_privkey_import_pkcs11( pgp_key, pkcs11_key, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
368 if (ret < 0)
370 fprintf (stderr, "*** Error loading url: %s\n",
371 gnutls_strerror (ret));
372 exit (1);
375 else
376 #endif /* ENABLE_PKCS11 */
378 gnutls_openpgp_privkey_t tmp_pgp_key;
380 data = load_file (pgp_keyfile);
381 if (data.data == NULL)
383 fprintf (stderr, "*** Error loading PGP key file.\n");
384 exit (1);
387 gnutls_openpgp_privkey_init (&tmp_pgp_key);
389 ret =
390 gnutls_openpgp_privkey_import (tmp_pgp_key, &data,
391 GNUTLS_OPENPGP_FMT_BASE64, NULL,
393 if (ret < 0)
395 fprintf (stderr,
396 "*** Error loading PGP key file: %s\n",
397 gnutls_strerror (ret));
398 exit (1);
401 if (HAVE_OPT(PGPSUBKEY))
403 ret =
404 gnutls_openpgp_privkey_set_preferred_key_id (tmp_pgp_key, keyid);
405 if (ret < 0)
407 fprintf (stderr,
408 "*** Error setting preferred sub key id (%s): %s\n",
409 OPT_ARG(PGPSUBKEY), gnutls_strerror (ret));
410 exit (1);
414 ret = gnutls_privkey_import_openpgp( pgp_key, tmp_pgp_key, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
415 if (ret < 0)
417 fprintf (stderr, "*** Error loading url: %s\n",
418 gnutls_strerror (ret));
419 exit (1);
422 unload_file (&data);
426 fprintf (stdout, "Processed 1 client PGP certificate...\n");
428 #endif
432 #define IS_NEWLINE(x) ((x[0] == '\n') || (x[0] == '\r'))
433 static int
434 read_yesno (const char *input_str)
436 char input[128];
438 fputs (input_str, stderr);
439 if (fgets (input, sizeof (input), stdin) == NULL)
440 return 0;
442 if (IS_NEWLINE(input))
443 return 0;
445 if (input[0] == 'y' || input[0] == 'Y')
446 return 1;
448 return 0;
451 /* converts a textual service or port to
452 * a service.
454 static const char* port_to_service(const char* sport)
456 unsigned int port;
457 struct servent * sr;
459 port = atoi(sport);
460 if (port == 0) return sport;
462 port = htons(port);
464 sr = getservbyport(port, udp?"udp":"tcp");
465 if (sr == NULL)
467 fprintf(stderr, "Warning: getservbyport() failed. Using port number as service.\n");
468 return sport;
471 return sr->s_name;
474 static int
475 cert_verify_callback (gnutls_session_t session)
477 int rc;
478 unsigned int status = 0;
479 int ssh = ENABLED_OPT(TOFU);
480 const char* txt_service;
482 if (!x509_cafile && !pgp_keyring)
483 return 0;
485 rc = cert_verify(session, hostname);
486 if (rc == 0)
488 printf ("*** Verifying server certificate failed...\n");
489 if (!insecure && !ssh)
490 return -1;
492 else if (ENABLED_OPT(OCSP))
493 { /* off-line verification succeeded. Try OCSP */
494 rc = cert_verify_ocsp(session);
495 if (rc == 0)
497 printf ("*** Verifying (with OCSP) server certificate failed...\n");
498 if (!insecure && !ssh)
499 return -1;
501 else if (rc == -1)
502 printf("*** OCSP response ignored\n");
505 if (ssh) /* try ssh auth */
507 unsigned int list_size;
508 const gnutls_datum_t * cert;
510 cert = gnutls_certificate_get_peers(session, &list_size);
511 if (cert == NULL)
513 fprintf(stderr, "Cannot obtain peer's certificate!\n");
514 return -1;
517 txt_service = port_to_service(service);
519 rc = gnutls_verify_stored_pubkey(NULL, NULL, hostname, txt_service,
520 GNUTLS_CRT_X509, cert, 0);
521 if (rc == GNUTLS_E_NO_CERTIFICATE_FOUND)
523 print_cert_info_compact(session);
524 fprintf(stderr, "Host %s (%s) has never been contacted before.\n", hostname, txt_service);
525 if (status == 0)
526 fprintf(stderr, "Its certificate is valid for %s.\n", hostname);
528 rc = read_yesno("Are you sure you want to trust it? (y/N): ");
529 if (rc == 0)
530 return -1;
532 else if (rc == GNUTLS_E_CERTIFICATE_KEY_MISMATCH)
534 print_cert_info_compact(session);
535 fprintf(stderr, "Warning: host %s is known and it is associated with a different key.\n", hostname);
536 fprintf(stderr, "It might be that the server has multiple keys, or an attacker replaced the key to eavesdrop this connection .\n");
537 if (status == 0)
538 fprintf(stderr, "Its certificate is valid for %s.\n", hostname);
540 rc = read_yesno("Do you trust the received key? (y/N): ");
541 if (rc == 0)
542 return -1;
544 else if (rc < 0)
546 fprintf(stderr, "gnutls_verify_stored_pubkey: %s\n", gnutls_strerror(rc));
547 return -1;
550 if (rc != 0)
552 rc = gnutls_store_pubkey(NULL, NULL, hostname, txt_service,
553 GNUTLS_CRT_X509, cert, 0, 0);
554 if (rc < 0)
555 fprintf(stderr, "Could not store key: %s\n", gnutls_strerror(rc));
559 return 0;
562 /* This callback should be associated with a session by calling
563 * gnutls_certificate_client_set_retrieve_function( session, cert_callback),
564 * before a handshake.
567 static int
568 cert_callback (gnutls_session_t session,
569 const gnutls_datum_t * req_ca_rdn, int nreqs,
570 const gnutls_pk_algorithm_t * sign_algos,
571 int sign_algos_length, gnutls_pcert_st **pcert,
572 unsigned int *pcert_length, gnutls_privkey_t * pkey)
574 char issuer_dn[256];
575 int i, ret, cert_type;
576 size_t len;
578 if (verbose)
580 /* Print the server's trusted CAs
582 if (nreqs > 0)
583 printf ("- Server's trusted authorities:\n");
584 else
585 printf ("- Server did not send us any trusted authorities names.\n");
587 /* print the names (if any) */
588 for (i = 0; i < nreqs; i++)
590 len = sizeof (issuer_dn);
591 ret = gnutls_x509_rdn_get (&req_ca_rdn[i], issuer_dn, &len);
592 if (ret >= 0)
594 printf (" [%d]: ", i);
595 printf ("%s\n", issuer_dn);
600 /* Select a certificate and return it.
601 * The certificate must be of any of the "sign algorithms"
602 * supported by the server.
605 cert_type = gnutls_certificate_type_get (session);
607 *pcert_length = 0;
609 if (cert_type == GNUTLS_CRT_X509)
611 if (x509_crt_size > 0)
613 if (x509_key != NULL)
615 *pkey = x509_key;
617 else
619 printf ("- Could not find a suitable key to send to server\n");
620 return -1;
623 *pcert_length = x509_crt_size;
624 *pcert = x509_crt;
628 else if (cert_type == GNUTLS_CRT_OPENPGP)
630 if (pgp_key != NULL)
632 *pkey = pgp_key;
634 *pcert_length = 1;
635 *pcert = &pgp_crt;
639 printf ("- Successfully sent %u certificate(s) to server.\n", *pcert_length);
640 return 0;
644 /* initializes a gnutls_session_t with some defaults.
646 static gnutls_session_t
647 init_tls_session (const char *hostname)
649 const char *err;
650 int ret;
651 gnutls_session_t session;
653 if (priorities == NULL)
654 priorities = "NORMAL";
656 if (udp)
658 gnutls_init (&session, GNUTLS_CLIENT|GNUTLS_DATAGRAM);
659 if (mtu)
660 gnutls_dtls_set_mtu(session, mtu);
662 else
663 gnutls_init (&session, GNUTLS_CLIENT);
665 if ((ret = gnutls_priority_set_direct (session, priorities, &err)) < 0)
667 if (ret == GNUTLS_E_INVALID_REQUEST) fprintf (stderr, "Syntax error at: %s\n", err);
668 else
669 fprintf(stderr, "Error in priorities: %s\n", gnutls_strerror(ret));
670 exit (1);
673 /* allow the use of private ciphersuites.
675 if (disable_extensions == 0)
677 gnutls_handshake_set_private_extensions (session, 1);
678 gnutls_server_name_set (session, GNUTLS_NAME_DNS, hostname,
679 strlen (hostname));
682 gnutls_dh_set_prime_bits (session, 512);
684 gnutls_credentials_set (session, GNUTLS_CRD_ANON, anon_cred);
685 if (srp_cred)
686 gnutls_credentials_set (session, GNUTLS_CRD_SRP, srp_cred);
687 if (psk_cred)
688 gnutls_credentials_set (session, GNUTLS_CRD_PSK, psk_cred);
689 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
691 gnutls_certificate_set_retrieve_function2 (xcred, cert_callback);
692 gnutls_certificate_set_verify_function (xcred, cert_verify_callback);
693 gnutls_certificate_set_verify_flags (xcred, 0);
695 /* send the fingerprint */
696 #ifdef ENABLE_OPENPGP
697 if (fingerprint != 0)
698 gnutls_openpgp_send_cert (session, GNUTLS_OPENPGP_CERT_FINGERPRINT);
699 #endif
701 /* use the max record size extension */
702 if (record_max_size > 0 && disable_extensions == 0)
704 if (gnutls_record_set_max_size (session, record_max_size) < 0)
706 fprintf (stderr,
707 "Cannot set the maximum record size to %d.\n",
708 record_max_size);
709 fprintf (stderr, "Possible values: 512, 1024, 2048, 4096.\n");
710 exit (1);
714 #ifdef ENABLE_SESSION_TICKET
715 if (disable_extensions == 0 && !HAVE_OPT(NOTICKET)t)
716 gnutls_session_ticket_enable_client (session);
717 #endif
719 return session;
722 static void cmd_parser (int argc, char **argv);
724 /* Returns zero if the error code was successfully handled.
726 static int
727 handle_error (socket_st * hd, int err)
729 int alert, ret;
730 const char *err_type, *str;
732 if (err >= 0 || err == GNUTLS_E_AGAIN || err == GNUTLS_E_INTERRUPTED)
733 return 0;
735 if (gnutls_error_is_fatal (err) == 0)
737 ret = 0;
738 err_type = "Non fatal";
740 else
742 ret = err;
743 err_type = "Fatal";
746 str = gnutls_strerror (err);
747 if (str == NULL)
748 str = str_unknown;
749 fprintf (stderr, "*** %s error: %s\n", err_type, str);
751 if (err == GNUTLS_E_WARNING_ALERT_RECEIVED
752 || err == GNUTLS_E_FATAL_ALERT_RECEIVED)
754 alert = gnutls_alert_get (hd->session);
755 str = gnutls_alert_get_name (alert);
756 if (str == NULL)
757 str = str_unknown;
758 printf ("*** Received alert [%d]: %s\n", alert, str);
761 check_rehandshake (hd, err);
763 return ret;
766 int starttls_alarmed = 0;
768 #ifndef _WIN32
769 static void
770 starttls_alarm (int signum)
772 starttls_alarmed = 1;
774 #endif
776 static void
777 tls_log_func (int level, const char *str)
779 fprintf (stderr, "|<%d>| %s", level, str);
782 #define IN_KEYBOARD 1
783 #define IN_NET 2
784 #define IN_NONE 0
785 /* returns IN_KEYBOARD for keyboard input and IN_NET for network input
787 static int check_net_or_keyboard_input(socket_st* hd)
789 int maxfd;
790 fd_set rset;
791 int err;
792 struct timeval tv;
796 FD_ZERO (&rset);
797 FD_SET (hd->fd, &rset);
799 #ifndef _WIN32
800 FD_SET (fileno (stdin), &rset);
801 maxfd = MAX (fileno (stdin), hd->fd);
802 #else
803 maxfd = hd->fd;
804 #endif
806 tv.tv_sec = 0;
807 tv.tv_usec = 50 * 1000;
809 if (hd->secure == 1)
810 if (gnutls_record_check_pending(hd->session))
811 return IN_NET;
813 err = select (maxfd + 1, &rset, NULL, NULL, &tv);
814 if (err < 0)
815 continue;
817 if (FD_ISSET (hd->fd, &rset))
818 return IN_NET;
820 #ifdef _WIN32
822 int state;
823 state = WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 200);
825 if (state == WAIT_OBJECT_0)
826 return IN_KEYBOARD;
828 #else
829 if (FD_ISSET (fileno (stdin), &rset))
830 return IN_KEYBOARD;
831 #endif
833 while(err == 0);
835 return IN_NONE;
839 main (int argc, char **argv)
841 int ret;
842 int ii, i, inp;
843 char buffer[MAX_BUF + 1];
844 char *session_data = NULL;
845 char *session_id = NULL;
846 size_t session_data_size;
847 size_t session_id_size = 0;
848 int user_term = 0, retval = 0;
849 socket_st hd;
850 ssize_t bytes;
852 set_program_name (argv[0]);
853 cmd_parser (argc, argv);
855 gnutls_global_set_log_function (tls_log_func);
856 gnutls_global_set_log_level (OPT_VALUE_DEBUG);
858 if ((ret = gnutls_global_init ()) < 0)
860 fprintf (stderr, "global_init: %s\n", gnutls_strerror (ret));
861 exit (1);
864 #ifdef ENABLE_PKCS11
865 pkcs11_common ();
866 #endif
868 if (hostname == NULL)
870 fprintf (stderr, "No hostname given\n");
871 exit (1);
874 sockets_init ();
876 init_global_tls_stuff ();
878 socket_open (&hd, hostname, service, udp);
879 socket_connect (&hd);
881 hd.session = init_tls_session (hostname);
882 if (starttls)
883 goto after_handshake;
885 for (i = 0; i < 2; i++)
889 if (i == 1)
891 hd.session = init_tls_session (hostname);
892 gnutls_session_set_data (hd.session, session_data,
893 session_data_size);
894 free (session_data);
897 ret = do_handshake (&hd);
899 if (ret < 0)
901 fprintf (stderr, "*** Handshake has failed\n");
902 gnutls_perror (ret);
903 gnutls_deinit (hd.session);
904 return 1;
906 else
908 printf ("- Handshake was completed\n");
909 if (gnutls_session_is_resumed (hd.session) != 0)
910 printf ("*** This is a resumed session\n");
913 if (resume != 0 && i == 0)
916 gnutls_session_get_data (hd.session, NULL, &session_data_size);
917 session_data = malloc (session_data_size);
919 gnutls_session_get_data (hd.session, session_data,
920 &session_data_size);
922 gnutls_session_get_id (hd.session, NULL, &session_id_size);
924 session_id = malloc (session_id_size);
925 gnutls_session_get_id (hd.session, session_id, &session_id_size);
927 printf ("- Disconnecting\n");
928 socket_bye (&hd);
930 printf
931 ("\n\n- Connecting again- trying to resume previous session\n");
932 socket_open (&hd, hostname, service, udp);
933 socket_connect (&hd);
935 else
937 break;
941 after_handshake:
943 /* Warning! Do not touch this text string, it is used by external
944 programs to search for when gnutls-cli has reached this point. */
945 printf ("\n- Simple Client Mode:\n\n");
947 if (rehandshake)
949 ret = do_handshake (&hd);
951 if (ret < 0)
953 fprintf (stderr, "*** ReHandshake has failed\n");
954 gnutls_perror (ret);
955 gnutls_deinit (hd.session);
956 return 1;
958 else
960 printf ("- ReHandshake was completed\n");
964 #ifndef _WIN32
965 signal (SIGALRM, &starttls_alarm);
966 #endif
968 fflush (stdout);
969 fflush (stderr);
971 /* do not buffer */
972 #if !(defined _WIN32 || defined __WIN32__)
973 setbuf (stdin, NULL);
974 #endif
975 setbuf (stdout, NULL);
976 setbuf (stderr, NULL);
978 for (;;)
980 if (starttls_alarmed && !hd.secure)
982 /* Warning! Do not touch this text string, it is used by
983 external programs to search for when gnutls-cli has
984 reached this point. */
985 fprintf (stderr, "*** Starting TLS handshake\n");
986 ret = do_handshake (&hd);
987 if (ret < 0)
989 fprintf (stderr, "*** Handshake has failed\n");
990 user_term = 1;
991 retval = 1;
992 break;
996 inp = check_net_or_keyboard_input(&hd);
998 if (inp == IN_NET)
1000 memset (buffer, 0, MAX_BUF + 1);
1001 ret = socket_recv (&hd, buffer, MAX_BUF);
1003 if (ret == 0)
1005 printf ("- Peer has closed the GnuTLS connection\n");
1006 break;
1008 else if (handle_error (&hd, ret) < 0 && user_term == 0)
1010 fprintf (stderr,
1011 "*** Server has terminated the connection abnormally.\n");
1012 retval = 1;
1013 break;
1015 else if (ret > 0)
1017 if (verbose != 0)
1018 printf ("- Received[%d]: ", ret);
1019 for (ii = 0; ii < ret; ii++)
1021 fputc (buffer[ii], stdout);
1023 fflush (stdout);
1026 if (user_term != 0)
1027 break;
1030 if (inp == IN_KEYBOARD)
1032 if ((bytes = read (fileno (stdin), buffer, MAX_BUF - 1)) <= 0)
1034 if (hd.secure == 0)
1036 /* Warning! Do not touch this text string, it is
1037 used by external programs to search for when
1038 gnutls-cli has reached this point. */
1039 fprintf (stderr, "*** Starting TLS handshake\n");
1040 ret = do_handshake (&hd);
1041 clearerr (stdin);
1042 if (ret < 0)
1044 fprintf (stderr, "*** Handshake has failed\n");
1045 user_term = 1;
1046 retval = 1;
1047 break;
1050 else
1052 user_term = 1;
1053 break;
1055 continue;
1058 buffer[bytes] = 0;
1059 if (crlf != 0)
1061 char *b = strchr (buffer, '\n');
1062 if (b != NULL)
1064 strcpy (b, "\r\n");
1065 bytes++;
1069 ret = socket_send (&hd, buffer, bytes);
1071 if (ret > 0)
1073 if (verbose != 0)
1074 printf ("- Sent: %d bytes\n", ret);
1076 else
1077 handle_error (&hd, ret);
1082 if (user_term != 0)
1083 socket_bye (&hd);
1084 else
1085 gnutls_deinit (hd.session);
1087 #ifdef ENABLE_SRP
1088 if (srp_cred)
1089 gnutls_srp_free_client_credentials (srp_cred);
1090 #endif
1091 #ifdef ENABLE_PSK
1092 if (psk_cred)
1093 gnutls_psk_free_client_credentials (psk_cred);
1094 #endif
1096 gnutls_certificate_free_credentials (xcred);
1098 #ifdef ENABLE_ANON
1099 gnutls_anon_free_client_credentials (anon_cred);
1100 #endif
1102 gnutls_global_deinit ();
1104 return retval;
1107 static void
1108 cmd_parser (int argc, char **argv)
1110 const char* rest = NULL;
1112 int optct = optionProcess( &gnutls_cliOptions, argc, argv);
1113 argc -= optct;
1114 argv += optct;
1116 if (rest == NULL && argc > 0)
1117 rest = argv[0];
1119 if (HAVE_OPT(BENCHMARK_CIPHERS))
1121 benchmark_cipher(1, OPT_VALUE_DEBUG);
1122 exit(0);
1125 if (HAVE_OPT(BENCHMARK_SOFT_CIPHERS))
1127 benchmark_cipher(0, OPT_VALUE_DEBUG);
1128 exit(0);
1131 if (HAVE_OPT(BENCHMARK_TLS))
1133 benchmark_tls(OPT_VALUE_DEBUG);
1134 exit(0);
1137 if (HAVE_OPT(PRIORITY))
1139 priorities = OPT_ARG(PRIORITY);
1141 verbose = HAVE_OPT( VERBOSE);
1142 if (verbose)
1143 print_cert = 1;
1144 else
1145 print_cert = HAVE_OPT( PRINT_CERT);
1147 if (HAVE_OPT(LIST))
1149 print_list(priorities, verbose);
1150 exit(0);
1153 disable_extensions = HAVE_OPT( DISABLE_EXTENSIONS);
1154 starttls = HAVE_OPT(STARTTLS);
1155 resume = HAVE_OPT(RESUME);
1156 rehandshake = HAVE_OPT(REHANDSHAKE);
1157 insecure = HAVE_OPT(INSECURE);
1159 udp = HAVE_OPT(UDP);
1160 mtu = OPT_VALUE_MTU;
1162 if (HAVE_OPT(PORT))
1164 service = OPT_ARG(PORT);
1166 else
1168 service = "443";
1171 record_max_size = OPT_VALUE_RECORDSIZE;
1172 fingerprint = HAVE_OPT(FINGERPRINT);
1174 if (HAVE_OPT(X509FMTDER))
1175 x509ctype = GNUTLS_X509_FMT_DER;
1176 else
1177 x509ctype = GNUTLS_X509_FMT_PEM;
1179 if (HAVE_OPT(SRPUSERNAME))
1180 srp_username = OPT_ARG(SRPUSERNAME);
1182 if (HAVE_OPT(SRPPASSWD))
1183 srp_passwd = OPT_ARG(SRPPASSWD);
1185 if (HAVE_OPT(X509CAFILE))
1186 x509_cafile = OPT_ARG(X509CAFILE);
1187 else
1189 if (access(DEFAULT_CA_FILE, R_OK) == 0)
1190 x509_cafile = DEFAULT_CA_FILE;
1193 if (HAVE_OPT(X509CRLFILE))
1194 x509_crlfile = OPT_ARG(X509CRLFILE);
1196 if (HAVE_OPT(X509KEYFILE))
1197 x509_keyfile = OPT_ARG(X509KEYFILE);
1199 if (HAVE_OPT(X509CERTFILE))
1200 x509_certfile = OPT_ARG(X509CERTFILE);
1202 if (HAVE_OPT(PGPKEYFILE))
1203 pgp_keyfile = OPT_ARG(PGPKEYFILE);
1205 if (HAVE_OPT(PGPCERTFILE))
1206 pgp_certfile = OPT_ARG(PGPCERTFILE);
1208 if (HAVE_OPT(PSKUSERNAME))
1209 psk_username = OPT_ARG(PSKUSERNAME);
1211 if (HAVE_OPT(PSKKEY))
1213 psk_key.data = (unsigned char *) OPT_ARG(PSKKEY);
1214 psk_key.size = strlen (OPT_ARG(PSKKEY));
1216 else
1217 psk_key.size = 0;
1219 if (HAVE_OPT(PGPKEYRING))
1220 pgp_keyring = OPT_ARG(PGPKEYRING);
1222 crlf = HAVE_OPT(CRLF);
1224 if (rest != NULL)
1225 hostname = rest;
1227 if (hostname == NULL)
1229 fprintf(stderr, "No hostname specified\n");
1230 exit(1);
1234 void cli_version (void);
1236 void
1237 cli_version (void)
1239 const char *p = PACKAGE_NAME;
1240 if (strcmp (gnutls_check_version (NULL), PACKAGE_VERSION) != 0)
1241 p = PACKAGE_STRING;
1242 version_etc (stdout, program_name, p, gnutls_check_version (NULL),
1243 "Nikos Mavrogiannopoulos", (char *) NULL);
1247 static void
1248 check_rehandshake (socket_st * socket, int ret)
1250 if (socket->secure && ret == GNUTLS_E_REHANDSHAKE)
1252 /* There is a race condition here. If application
1253 * data is sent after the rehandshake request,
1254 * the server thinks we ignored his request.
1255 * This is a bad design of this client.
1257 printf ("*** Received rehandshake request\n");
1258 /* gnutls_alert_send( session, GNUTLS_AL_WARNING, GNUTLS_A_NO_RENEGOTIATION); */
1260 ret = do_handshake (socket);
1262 if (ret == 0)
1264 printf ("*** Rehandshake was performed.\n");
1266 else
1268 printf ("*** Rehandshake Failed.\n");
1274 static int
1275 do_handshake (socket_st * socket)
1277 int ret;
1279 gnutls_transport_set_ptr (socket->session,
1280 (gnutls_transport_ptr_t)
1281 gl_fd_to_handle (socket->fd));
1284 ret = gnutls_handshake (socket->session);
1286 if (ret < 0)
1288 handle_error (socket, ret);
1291 while (ret < 0 && gnutls_error_is_fatal (ret) == 0);
1293 if (ret == 0)
1295 /* print some information */
1296 print_info (socket->session, print_cert);
1297 socket->secure = 1;
1299 else
1301 gnutls_alert_send_appropriate (socket->session, ret);
1302 shutdown (socket->fd, SHUT_RDWR);
1304 return ret;
1307 static int
1308 srp_username_callback (gnutls_session_t session,
1309 char **username, char **password)
1311 if (srp_username == NULL || srp_passwd == NULL)
1313 return -1;
1316 *username = gnutls_strdup (srp_username);
1317 *password = gnutls_strdup (srp_passwd);
1319 return 0;
1322 static int
1323 psk_callback (gnutls_session_t session, char **username, gnutls_datum_t * key)
1325 const char *hint = gnutls_psk_client_get_hint (session);
1326 char *rawkey;
1327 char *passwd;
1328 int ret;
1329 size_t res_size;
1330 gnutls_datum_t tmp;
1332 printf ("- PSK client callback. ");
1333 if (hint)
1334 printf ("PSK hint '%s'\n", hint);
1335 else
1336 printf ("No PSK hint\n");
1338 if (HAVE_OPT(PSKUSERNAME))
1339 *username = gnutls_strdup (OPT_ARG(PSKUSERNAME));
1340 else
1342 char *tmp = NULL;
1343 size_t n;
1345 printf ("Enter PSK identity: ");
1346 fflush (stdout);
1347 getline (&tmp, &n, stdin);
1349 if (tmp == NULL)
1351 fprintf (stderr, "No username given, aborting...\n");
1352 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1355 if (tmp[strlen (tmp) - 1] == '\n')
1356 tmp[strlen (tmp) - 1] = '\0';
1357 if (tmp[strlen (tmp) - 1] == '\r')
1358 tmp[strlen (tmp) - 1] = '\0';
1360 *username = gnutls_strdup (tmp);
1361 free (tmp);
1363 if (!*username)
1364 return GNUTLS_E_MEMORY_ERROR;
1366 passwd = getpass ("Enter key: ");
1367 if (passwd == NULL)
1369 fprintf (stderr, "No key given, aborting...\n");
1370 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1373 tmp.data = (void*)passwd;
1374 tmp.size = strlen (passwd);
1376 res_size = tmp.size / 2 + 1;
1377 rawkey = gnutls_malloc (res_size);
1378 if (rawkey == NULL)
1379 return GNUTLS_E_MEMORY_ERROR;
1381 ret = gnutls_hex_decode (&tmp, rawkey, &res_size);
1382 if (ret < 0)
1384 fprintf (stderr, "Error deriving password: %s\n",
1385 gnutls_strerror (ret));
1386 gnutls_free (*username);
1387 return ret;
1390 key->data = (void*)rawkey;
1391 key->size = res_size;
1393 if (HAVE_OPT(DEBUG))
1395 char hexkey[41];
1396 res_size = sizeof (hexkey);
1397 gnutls_hex_encode (key, hexkey, &res_size);
1398 fprintf (stderr, "PSK username: %s\n", *username);
1399 fprintf (stderr, "PSK hint: %s\n", hint);
1400 fprintf (stderr, "PSK key: %s\n", hexkey);
1403 return 0;
1406 static void
1407 init_global_tls_stuff (void)
1409 int ret;
1411 /* X509 stuff */
1412 if (gnutls_certificate_allocate_credentials (&xcred) < 0)
1414 fprintf (stderr, "Certificate allocation memory error\n");
1415 exit (1);
1418 if (x509_cafile != NULL)
1420 ret = gnutls_certificate_set_x509_trust_file (xcred,
1421 x509_cafile, x509ctype);
1422 if (ret < 0)
1424 fprintf (stderr, "Error setting the x509 trust file\n");
1426 else
1428 printf ("Processed %d CA certificate(s).\n", ret);
1431 if (x509_crlfile != NULL)
1433 ret = gnutls_certificate_set_x509_crl_file (xcred, x509_crlfile,
1434 x509ctype);
1435 if (ret < 0)
1437 fprintf (stderr, "Error setting the x509 CRL file\n");
1439 else
1441 printf ("Processed %d CRL(s).\n", ret);
1445 load_keys ();
1447 #ifdef ENABLE_OPENPGP
1448 if (pgp_keyring != NULL)
1450 ret =
1451 gnutls_certificate_set_openpgp_keyring_file (xcred, pgp_keyring,
1452 GNUTLS_OPENPGP_FMT_BASE64);
1453 if (ret < 0)
1455 fprintf (stderr, "Error setting the OpenPGP keyring file\n");
1458 #endif
1460 #ifdef ENABLE_SRP
1461 if (srp_username && srp_passwd)
1463 /* SRP stuff */
1464 if (gnutls_srp_allocate_client_credentials (&srp_cred) < 0)
1466 fprintf (stderr, "SRP authentication error\n");
1469 gnutls_srp_set_client_credentials_function (srp_cred,
1470 srp_username_callback);
1472 #endif
1474 #ifdef ENABLE_PSK
1475 /* PSK stuff */
1476 if (gnutls_psk_allocate_client_credentials (&psk_cred) < 0)
1478 fprintf (stderr, "PSK authentication error\n");
1481 if (psk_username && psk_key.data)
1483 ret = gnutls_psk_set_client_credentials (psk_cred,
1484 psk_username, &psk_key,
1485 GNUTLS_PSK_KEY_HEX);
1486 if (ret < 0)
1488 fprintf (stderr, "Error setting the PSK credentials: %s\n",
1489 gnutls_strerror (ret));
1492 else
1493 gnutls_psk_set_client_credentials_function (psk_cred, psk_callback);
1494 #endif
1496 #ifdef ENABLE_ANON
1497 /* ANON stuff */
1498 if (gnutls_anon_allocate_client_credentials (&anon_cred) < 0)
1500 fprintf (stderr, "Anonymous authentication error\n");
1502 #endif
1506 /* OCSP check for the peer's certificate. Should be called
1507 * only after the certificate list verication is complete.
1508 * Returns:
1509 * 0: certificate is revoked
1510 * 1: certificate is ok
1511 * -1: dunno
1513 static int
1514 cert_verify_ocsp (gnutls_session_t session)
1516 gnutls_x509_crt_t crt, issuer;
1517 const gnutls_datum_t *cert_list;
1518 unsigned int cert_list_size = 0;
1519 int deinit_issuer = 0;
1520 gnutls_datum_t resp;
1521 int ret;
1523 cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
1524 if (cert_list_size == 0)
1526 fprintf (stderr, "No certificates found!\n");
1527 return -1;
1530 gnutls_x509_crt_init (&crt);
1531 ret =
1532 gnutls_x509_crt_import (crt, &cert_list[0],
1533 GNUTLS_X509_FMT_DER);
1534 if (ret < 0)
1536 fprintf (stderr, "Decoding error: %s\n",
1537 gnutls_strerror (ret));
1538 return -1;
1541 ret = gnutls_certificate_get_issuer(xcred, crt, &issuer, 0);
1542 if (ret < 0 && cert_list_size > 1)
1544 gnutls_x509_crt_init(&issuer);
1545 ret = gnutls_x509_crt_import(issuer, &cert_list[1], GNUTLS_X509_FMT_DER);
1546 if (ret < 0)
1548 fprintf (stderr, "Decoding error: %s\n",
1549 gnutls_strerror (ret));
1550 return -1;
1552 deinit_issuer = 1;
1554 else if (ret < 0)
1556 fprintf(stderr, "Cannot find issuer\n");
1557 ret = -1;
1558 goto cleanup;
1561 ret = send_ocsp_request(NULL, crt, issuer, &resp, 1);
1562 if (ret < 0)
1564 fprintf(stderr, "Cannot contact OCSP server\n");
1565 ret = -1;
1566 goto cleanup;
1569 /* verify and check the response for revoked cert */
1570 ret = check_ocsp_response(issuer, &resp);
1572 cleanup:
1573 if (deinit_issuer)
1574 gnutls_x509_crt_deinit (issuer);
1575 gnutls_x509_crt_deinit (crt);
1577 return ret;