The high level functions accept sflags and vflags as separate options.
[gnutls.git] / src / cli.c
bloba4bcc465645b67746225acc8ef8bb26eba20ce5c
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>
39 #include <ctype.h>
41 #include <gnutls/gnutls.h>
42 #include <gnutls/abstract.h>
43 #include <gnutls/dtls.h>
44 #include <gnutls/x509.h>
45 #include <gnutls/openpgp.h>
46 #include <gnutls/pkcs11.h>
48 /* Gnulib portability files. */
49 #include <progname.h>
50 #include <version-etc.h>
51 #include <read-file.h>
52 #include <getpass.h>
53 #include <minmax.h>
55 #include "sockets.h"
56 #include "benchmark.h"
58 #ifdef HAVE_DANE
59 #include <gnutls/dane.h>
60 #endif
62 #include <common.h>
63 #include <socket.h>
65 #include <cli-args.h>
66 #include <ocsptool-common.h>
68 #define MAX_BUF 4096
70 /* global stuff here */
71 int resume, starttls, insecure, rehandshake, udp, mtu;
72 const char *hostname = NULL;
73 const char *service = NULL;
74 int record_max_size;
75 int status_request_ocsp;
76 int fingerprint;
77 int crlf;
78 unsigned int verbose = 0;
79 int print_cert;
81 const char *srp_passwd = NULL;
82 const char *srp_username = NULL;
83 const char *pgp_keyfile = NULL;
84 const char *pgp_certfile = NULL;
85 const char *pgp_keyring = NULL;
86 const char *x509_keyfile = NULL;
87 const char *x509_certfile = NULL;
88 const char *x509_cafile = NULL;
89 const char *x509_crlfile = NULL;
90 static int x509ctype;
91 static int disable_extensions;
92 static const char * priorities = NULL;
94 const char *psk_username = NULL;
95 gnutls_datum_t psk_key = { NULL, 0 };
97 static gnutls_srp_client_credentials_t srp_cred;
98 static gnutls_psk_client_credentials_t psk_cred;
99 static gnutls_anon_client_credentials_t anon_cred;
100 static gnutls_certificate_credentials_t xcred;
102 /* end of global stuff */
104 /* prototypes */
106 static void check_rehandshake (socket_st * socket, int ret);
107 static int do_handshake (socket_st * socket);
108 static void init_global_tls_stuff (void);
109 static int cert_verify_ocsp (gnutls_session_t session);
111 #define MAX_CRT 6
112 static unsigned int x509_crt_size;
113 static gnutls_pcert_st x509_crt[MAX_CRT];
114 static gnutls_privkey_t x509_key = NULL;
116 static gnutls_pcert_st pgp_crt;
117 static gnutls_privkey_t pgp_key = NULL;
119 static void
120 get_keyid (gnutls_openpgp_keyid_t keyid, const char *str)
122 size_t keyid_size = sizeof (keyid);
124 if (strlen (str) != 16)
126 fprintf (stderr,
127 "The OpenPGP subkey ID has to be 16 hexadecimal characters.\n");
128 exit (1);
131 if (gnutls_hex2bin (str, strlen (str), keyid, &keyid_size) < 0)
133 fprintf (stderr, "Error converting hex string: %s.\n", str);
134 exit (1);
137 return;
140 /* Load the certificate and the private key.
142 static void
143 load_keys (void)
145 unsigned int crt_num;
146 int ret;
147 unsigned int i;
148 gnutls_datum_t data = { NULL, 0 };
149 gnutls_x509_crt_t crt_list[MAX_CRT];
150 unsigned char keyid[GNUTLS_OPENPGP_KEYID_SIZE];
152 if (x509_certfile != NULL && x509_keyfile != NULL)
154 #ifdef ENABLE_PKCS11
155 if (strncmp (x509_certfile, "pkcs11:", 7) == 0)
157 crt_num = 1;
158 gnutls_x509_crt_init (&crt_list[0]);
159 gnutls_x509_crt_set_pin_function(crt_list[0], pin_callback, NULL);
161 ret =
162 gnutls_x509_crt_import_pkcs11_url (crt_list[0], x509_certfile, 0);
164 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
165 ret =
166 gnutls_x509_crt_import_pkcs11_url (crt_list[0], x509_certfile,
167 GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
169 if (ret < 0)
171 fprintf (stderr, "*** Error loading cert file.\n");
172 exit (1);
174 x509_crt_size = 1;
176 else
177 #endif /* ENABLE_PKCS11 */
180 ret = gnutls_load_file (x509_certfile, &data);
181 if (ret < 0)
183 fprintf (stderr, "*** Error loading cert file.\n");
184 exit (1);
187 crt_num = MAX_CRT;
188 ret =
189 gnutls_x509_crt_list_import (crt_list, &crt_num, &data,
190 x509ctype,
191 GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
192 if (ret < 0)
194 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
196 fprintf (stderr,
197 "*** Error loading cert file: Too many certs %d\n",
198 crt_num);
201 else
203 fprintf (stderr,
204 "*** Error loading cert file: %s\n",
205 gnutls_strerror (ret));
207 exit (1);
209 x509_crt_size = ret;
212 for (i=0;i<x509_crt_size;i++)
214 ret = gnutls_pcert_import_x509(&x509_crt[i], crt_list[i], 0);
215 if (ret < 0)
217 fprintf(stderr, "*** Error importing crt to pcert: %s\n",
218 gnutls_strerror(ret));
219 exit(1);
221 gnutls_x509_crt_deinit(crt_list[i]);
224 gnutls_free (data.data);
226 ret = gnutls_privkey_init(&x509_key);
227 if (ret < 0)
229 fprintf (stderr, "*** Error initializing key: %s\n",
230 gnutls_strerror (ret));
231 exit (1);
234 gnutls_privkey_set_pin_function(x509_key, pin_callback, NULL);
236 if (gnutls_url_is_supported(x509_keyfile) != 0)
238 ret =
239 gnutls_privkey_import_url (x509_key, x509_keyfile, 0);
240 if (ret < 0)
242 fprintf (stderr, "*** Error loading url: %s\n",
243 gnutls_strerror (ret));
244 exit (1);
247 else
249 ret = gnutls_load_file (x509_keyfile, &data);
250 if (ret < 0)
252 fprintf (stderr, "*** Error loading key file.\n");
253 exit (1);
256 ret = gnutls_privkey_import_x509_raw( x509_key, &data, x509ctype, NULL, 0);
257 if (ret < 0)
259 fprintf (stderr, "*** Error loading url: %s\n",
260 gnutls_strerror (ret));
261 exit (1);
264 gnutls_free(data.data);
267 fprintf (stdout, "Processed %d client X.509 certificates...\n",
268 x509_crt_size);
272 #ifdef ENABLE_OPENPGP
273 if (HAVE_OPT(PGPSUBKEY))
275 get_keyid (keyid, OPT_ARG(PGPSUBKEY));
278 if (pgp_certfile != NULL && pgp_keyfile != NULL)
280 gnutls_openpgp_crt_t tmp_pgp_crt;
282 ret = gnutls_load_file (pgp_certfile, &data);
283 if (ret < 0)
285 fprintf (stderr, "*** Error loading PGP cert file.\n");
286 exit (1);
289 gnutls_openpgp_crt_init (&tmp_pgp_crt);
291 ret =
292 gnutls_pcert_import_openpgp_raw (&pgp_crt, &data, GNUTLS_OPENPGP_FMT_BASE64, HAVE_OPT(PGPSUBKEY)?keyid:NULL, 0);
293 if (ret < 0)
295 fprintf (stderr,
296 "*** Error loading PGP cert file: %s\n",
297 gnutls_strerror (ret));
298 exit (1);
301 gnutls_free (data.data);
303 ret = gnutls_privkey_init(&pgp_key);
304 if (ret < 0)
306 fprintf (stderr, "*** Error initializing key: %s\n",
307 gnutls_strerror (ret));
308 exit (1);
311 gnutls_privkey_set_pin_function(pgp_key, pin_callback, NULL);
313 if (gnutls_url_is_supported (pgp_keyfile))
315 ret = gnutls_privkey_import_url( pgp_key, pgp_keyfile, 0);
316 if (ret < 0)
318 fprintf (stderr, "*** Error loading url: %s\n",
319 gnutls_strerror (ret));
320 exit (1);
323 else
325 ret = gnutls_load_file (pgp_keyfile, &data);
326 if (ret < 0)
328 fprintf (stderr, "*** Error loading key file.\n");
329 exit (1);
332 if (HAVE_OPT(PGPSUBKEY))
333 ret = gnutls_privkey_import_openpgp_raw( pgp_key, &data, x509ctype, keyid, NULL);
334 else
335 ret = gnutls_privkey_import_openpgp_raw( pgp_key, &data, x509ctype, NULL, NULL);
336 if (ret < 0)
338 fprintf (stderr, "*** Error loading url: %s\n",
339 gnutls_strerror (ret));
340 exit (1);
343 gnutls_free(data.data);
347 fprintf (stdout, "Processed 1 client PGP certificate...\n");
349 #endif
353 #define IS_NEWLINE(x) ((x[0] == '\n') || (x[0] == '\r'))
354 static int
355 read_yesno (const char *input_str)
357 char input[128];
359 fputs (input_str, stderr);
360 if (fgets (input, sizeof (input), stdin) == NULL)
361 return 0;
363 if (IS_NEWLINE(input))
364 return 0;
366 if (input[0] == 'y' || input[0] == 'Y')
367 return 1;
369 return 0;
372 /* converts a textual service or port to
373 * a service.
375 static const char* port_to_service(const char* sport)
377 unsigned int port;
378 struct servent * sr;
380 port = atoi(sport);
381 if (port == 0) return sport;
383 port = htons(port);
385 sr = getservbyport(port, udp?"udp":"tcp");
386 if (sr == NULL)
388 fprintf(stderr, "Warning: getservbyport() failed. Using port number as service.\n");
389 return sport;
392 return sr->s_name;
395 static int
396 cert_verify_callback (gnutls_session_t session)
398 int rc;
399 unsigned int status = 0;
400 int ssh = ENABLED_OPT(TOFU);
401 int dane = ENABLED_OPT(DANE);
402 int ca_verify = ENABLED_OPT(CA_VERIFICATION);
403 const char* txt_service;
405 print_cert_info (session, verbose, print_cert);
407 if (ca_verify)
409 rc = cert_verify(session, hostname);
410 if (rc == 0)
412 printf ("*** Verifying server certificate failed...\n");
413 if (!insecure && !ssh)
414 return -1;
416 else if (ENABLED_OPT(OCSP))
417 { /* off-line verification succeeded. Try OCSP */
418 rc = cert_verify_ocsp(session);
419 if (rc == 0)
421 printf ("*** Verifying (with OCSP) server certificate failed...\n");
422 if (!insecure && !ssh)
423 return -1;
425 else if (rc == -1)
426 printf("*** OCSP response ignored\n");
430 if (ssh) /* try ssh auth */
432 unsigned int list_size;
433 const gnutls_datum_t * cert;
435 cert = gnutls_certificate_get_peers(session, &list_size);
436 if (cert == NULL)
438 fprintf(stderr, "Cannot obtain peer's certificate!\n");
439 return -1;
442 txt_service = port_to_service(service);
444 rc = gnutls_verify_stored_pubkey(NULL, NULL, hostname, txt_service,
445 GNUTLS_CRT_X509, cert, 0);
446 if (rc == GNUTLS_E_NO_CERTIFICATE_FOUND)
448 print_cert_info_compact(session);
449 fprintf(stderr, "Host %s (%s) has never been contacted before.\n", hostname, txt_service);
450 if (status == 0)
451 fprintf(stderr, "Its certificate is valid for %s.\n", hostname);
453 rc = read_yesno("Are you sure you want to trust it? (y/N): ");
454 if (rc == 0)
455 return -1;
457 else if (rc == GNUTLS_E_CERTIFICATE_KEY_MISMATCH)
459 print_cert_info_compact(session);
460 fprintf(stderr, "Warning: host %s is known and it is associated with a different key.\n", hostname);
461 fprintf(stderr, "It might be that the server has multiple keys, or an attacker replaced the key to eavesdrop this connection .\n");
462 if (status == 0)
463 fprintf(stderr, "Its certificate is valid for %s.\n", hostname);
465 rc = read_yesno("Do you trust the received key? (y/N): ");
466 if (rc == 0)
467 return -1;
469 else if (rc < 0)
471 fprintf(stderr, "gnutls_verify_stored_pubkey: %s\n", gnutls_strerror(rc));
472 return -1;
475 if (rc != 0)
477 rc = gnutls_store_pubkey(NULL, NULL, hostname, txt_service,
478 GNUTLS_CRT_X509, cert, 0, 0);
479 if (rc < 0)
480 fprintf(stderr, "Could not store key: %s\n", gnutls_strerror(rc));
484 #ifdef HAVE_DANE
485 if (dane) /* try DANE auth */
487 rc = dane_verify_session_crt( NULL, session, hostname, udp?"udp":"tcp", atoi(service),
488 DANE_F_IGNORE_LOCAL_RESOLVER, 0, &status);
489 if (rc < 0)
491 fprintf(stderr, "*** DANE verification error: %s\n", dane_strerror(rc));
492 if (!insecure)
493 return -1;
495 else
497 if (status != 0)
499 fprintf(stderr, "*** DANE certificate verification failed (flags %x).\n", status);
500 if (status & DANE_VERIFY_CA_CONSTRAINS_VIOLATED)
501 fprintf(stderr, "- CA constrains were violated.\n");
502 if (status & DANE_VERIFY_CERT_DIFFERS)
503 fprintf(stderr, "- The certificate differs.\n");
504 if (status & DANE_VERIFY_NO_DANE_INFO)
505 fprintf(stderr, "- There was no DANE information.\n");
506 if (!insecure)
507 return -1;
509 else
510 printf("- DANE verification didn't reject the certificate.\n");
514 #endif
516 return 0;
519 /* This callback should be associated with a session by calling
520 * gnutls_certificate_client_set_retrieve_function( session, cert_callback),
521 * before a handshake.
524 static int
525 cert_callback (gnutls_session_t session,
526 const gnutls_datum_t * req_ca_rdn, int nreqs,
527 const gnutls_pk_algorithm_t * sign_algos,
528 int sign_algos_length, gnutls_pcert_st **pcert,
529 unsigned int *pcert_length, gnutls_privkey_t * pkey)
531 char issuer_dn[256];
532 int i, ret, cert_type;
533 size_t len;
535 if (verbose)
537 /* Print the server's trusted CAs
539 if (nreqs > 0)
540 printf ("- Server's trusted authorities:\n");
541 else
542 printf ("- Server did not send us any trusted authorities names.\n");
544 /* print the names (if any) */
545 for (i = 0; i < nreqs; i++)
547 len = sizeof (issuer_dn);
548 ret = gnutls_x509_rdn_get (&req_ca_rdn[i], issuer_dn, &len);
549 if (ret >= 0)
551 printf (" [%d]: ", i);
552 printf ("%s\n", issuer_dn);
557 /* Select a certificate and return it.
558 * The certificate must be of any of the "sign algorithms"
559 * supported by the server.
562 cert_type = gnutls_certificate_type_get (session);
564 *pcert_length = 0;
566 if (cert_type == GNUTLS_CRT_X509)
568 if (x509_crt_size > 0)
570 if (x509_key != NULL)
572 *pkey = x509_key;
574 else
576 printf ("- Could not find a suitable key to send to server\n");
577 return -1;
580 *pcert_length = x509_crt_size;
581 *pcert = x509_crt;
585 else if (cert_type == GNUTLS_CRT_OPENPGP)
587 if (pgp_key != NULL)
589 *pkey = pgp_key;
591 *pcert_length = 1;
592 *pcert = &pgp_crt;
596 printf ("- Successfully sent %u certificate(s) to server.\n", *pcert_length);
597 return 0;
601 /* initializes a gnutls_session_t with some defaults.
603 static gnutls_session_t
604 init_tls_session (const char *hostname)
606 const char *err;
607 int ret;
608 gnutls_session_t session;
610 if (priorities == NULL)
611 priorities = "NORMAL";
613 if (udp)
615 gnutls_init (&session, GNUTLS_CLIENT|GNUTLS_DATAGRAM);
616 if (mtu)
617 gnutls_dtls_set_mtu(session, mtu);
619 else
620 gnutls_init (&session, GNUTLS_CLIENT);
622 if ((ret = gnutls_priority_set_direct (session, priorities, &err)) < 0)
624 if (ret == GNUTLS_E_INVALID_REQUEST) fprintf (stderr, "Syntax error at: %s\n", err);
625 else
626 fprintf(stderr, "Error in priorities: %s\n", gnutls_strerror(ret));
627 exit (1);
630 /* allow the use of private ciphersuites.
632 if (disable_extensions == 0)
634 if (!isdigit(hostname[0]) && strchr(hostname, ':') == 0)
635 gnutls_server_name_set (session, GNUTLS_NAME_DNS, hostname,
636 strlen (hostname));
639 if (HAVE_OPT(DH_BITS))
640 gnutls_dh_set_prime_bits( session, OPT_VALUE_DH_BITS);
642 gnutls_credentials_set (session, GNUTLS_CRD_ANON, anon_cred);
643 if (srp_cred)
644 gnutls_credentials_set (session, GNUTLS_CRD_SRP, srp_cred);
645 if (psk_cred)
646 gnutls_credentials_set (session, GNUTLS_CRD_PSK, psk_cred);
647 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
649 gnutls_certificate_set_retrieve_function2 (xcred, cert_callback);
650 gnutls_certificate_set_verify_function (xcred, cert_verify_callback);
652 /* send the fingerprint */
653 #ifdef ENABLE_OPENPGP
654 if (fingerprint != 0)
655 gnutls_openpgp_send_cert (session, GNUTLS_OPENPGP_CERT_FINGERPRINT);
656 #endif
658 /* use the max record size extension */
659 if (record_max_size > 0 && disable_extensions == 0)
661 if (gnutls_record_set_max_size (session, record_max_size) < 0)
663 fprintf (stderr,
664 "Cannot set the maximum record size to %d.\n",
665 record_max_size);
666 fprintf (stderr, "Possible values: 512, 1024, 2048, 4096.\n");
667 exit (1);
671 if (HAVE_OPT(HEARTBEAT))
672 gnutls_heartbeat_enable (session, GNUTLS_HB_PEER_ALLOWED_TO_SEND);
674 /* OCSP status-request TLS extension */
675 if (status_request_ocsp > 0 && disable_extensions == 0)
677 if (gnutls_ocsp_status_request_enable_client (session, NULL, 0, NULL) < 0)
679 fprintf (stderr, "Cannot set OCSP status request information.\n");
680 exit (1);
684 #ifdef ENABLE_SESSION_TICKET
685 if (disable_extensions == 0 && !HAVE_OPT(NOTICKET)t)
686 gnutls_session_ticket_enable_client (session);
687 #endif
689 return session;
692 static void cmd_parser (int argc, char **argv);
694 /* Returns zero if the error code was successfully handled.
696 static int
697 handle_error (socket_st * hd, int err)
699 int alert, ret;
700 const char *err_type, *str;
702 if (err >= 0 || err == GNUTLS_E_AGAIN || err == GNUTLS_E_INTERRUPTED)
703 return 0;
705 if (gnutls_error_is_fatal (err) == 0)
707 ret = 0;
708 err_type = "Non fatal";
710 else
712 ret = err;
713 err_type = "Fatal";
716 str = gnutls_strerror (err);
717 if (str == NULL)
718 str = str_unknown;
719 fprintf (stderr, "*** %s error: %s\n", err_type, str);
721 if (err == GNUTLS_E_WARNING_ALERT_RECEIVED
722 || err == GNUTLS_E_FATAL_ALERT_RECEIVED)
724 alert = gnutls_alert_get (hd->session);
725 str = gnutls_alert_get_name (alert);
726 if (str == NULL)
727 str = str_unknown;
728 printf ("*** Received alert [%d]: %s\n", alert, str);
731 check_rehandshake (hd, err);
733 return ret;
736 int starttls_alarmed = 0;
738 #ifndef _WIN32
739 static void
740 starttls_alarm (int signum)
742 starttls_alarmed = 1;
744 #endif
746 static void
747 tls_log_func (int level, const char *str)
749 fprintf (stderr, "|<%d>| %s", level, str);
752 #define IN_KEYBOARD 1
753 #define IN_NET 2
754 #define IN_NONE 0
755 /* returns IN_KEYBOARD for keyboard input and IN_NET for network input
757 static int check_net_or_keyboard_input(socket_st* hd)
759 int maxfd;
760 fd_set rset;
761 int err;
762 struct timeval tv;
766 FD_ZERO (&rset);
767 FD_SET (hd->fd, &rset);
769 #ifndef _WIN32
770 FD_SET (fileno (stdin), &rset);
771 maxfd = MAX (fileno (stdin), hd->fd);
772 #else
773 maxfd = hd->fd;
774 #endif
776 tv.tv_sec = 0;
777 tv.tv_usec = 50 * 1000;
779 if (hd->secure == 1)
780 if (gnutls_record_check_pending(hd->session))
781 return IN_NET;
783 err = select (maxfd + 1, &rset, NULL, NULL, &tv);
784 if (err < 0)
785 continue;
787 if (FD_ISSET (hd->fd, &rset))
788 return IN_NET;
790 #ifdef _WIN32
792 int state;
793 state = WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 200);
795 if (state == WAIT_OBJECT_0)
796 return IN_KEYBOARD;
798 #else
799 if (FD_ISSET (fileno (stdin), &rset))
800 return IN_KEYBOARD;
801 #endif
803 while(err == 0);
805 return IN_NONE;
809 main (int argc, char **argv)
811 int ret;
812 int ii, i, inp;
813 char buffer[MAX_BUF + 1];
814 char *session_data = NULL;
815 char *session_id = NULL;
816 size_t session_data_size;
817 size_t session_id_size = 0;
818 int user_term = 0, retval = 0;
819 socket_st hd;
820 ssize_t bytes;
822 set_program_name (argv[0]);
823 cmd_parser (argc, argv);
825 gnutls_global_set_log_function (tls_log_func);
826 gnutls_global_set_log_level (OPT_VALUE_DEBUG);
828 if ((ret = gnutls_global_init ()) < 0)
830 fprintf (stderr, "global_init: %s\n", gnutls_strerror (ret));
831 exit (1);
834 #ifdef ENABLE_PKCS11
835 // pkcs11_common ();
836 #endif
838 if (hostname == NULL)
840 fprintf (stderr, "No hostname given\n");
841 exit (1);
844 sockets_init ();
846 init_global_tls_stuff ();
848 socket_open (&hd, hostname, service, udp);
849 socket_connect (&hd);
851 hd.session = init_tls_session (hostname);
852 if (starttls)
853 goto after_handshake;
855 for (i = 0; i < 2; i++)
859 if (i == 1)
861 hd.session = init_tls_session (hostname);
862 gnutls_session_set_data (hd.session, session_data,
863 session_data_size);
864 free (session_data);
867 ret = do_handshake (&hd);
869 if (ret < 0)
871 fprintf (stderr, "*** Handshake has failed\n");
872 gnutls_perror (ret);
873 gnutls_deinit (hd.session);
874 return 1;
876 else
878 printf ("- Handshake was completed\n");
879 if (gnutls_session_is_resumed (hd.session) != 0)
880 printf ("*** This is a resumed session\n");
883 if (resume != 0 && i == 0)
886 gnutls_session_get_data (hd.session, NULL, &session_data_size);
887 session_data = malloc (session_data_size);
889 gnutls_session_get_data (hd.session, session_data,
890 &session_data_size);
892 gnutls_session_get_id (hd.session, NULL, &session_id_size);
894 session_id = malloc (session_id_size);
895 gnutls_session_get_id (hd.session, session_id, &session_id_size);
897 printf ("- Disconnecting\n");
898 socket_bye (&hd);
900 printf
901 ("\n\n- Connecting again- trying to resume previous session\n");
902 socket_open (&hd, hostname, service, udp);
903 socket_connect (&hd);
905 else
907 break;
911 after_handshake:
913 /* Warning! Do not touch this text string, it is used by external
914 programs to search for when gnutls-cli has reached this point. */
915 printf ("\n- Simple Client Mode:\n\n");
917 if (rehandshake)
919 ret = do_handshake (&hd);
921 if (ret < 0)
923 fprintf (stderr, "*** ReHandshake has failed\n");
924 gnutls_perror (ret);
925 gnutls_deinit (hd.session);
926 return 1;
928 else
930 printf ("- ReHandshake was completed\n");
934 #ifndef _WIN32
935 signal (SIGALRM, &starttls_alarm);
936 #endif
938 fflush (stdout);
939 fflush (stderr);
941 /* do not buffer */
942 #ifndef _WIN32
943 setbuf (stdin, NULL);
944 #endif
945 setbuf (stdout, NULL);
946 setbuf (stderr, NULL);
948 for (;;)
950 if (starttls_alarmed && !hd.secure)
952 /* Warning! Do not touch this text string, it is used by
953 external programs to search for when gnutls-cli has
954 reached this point. */
955 fprintf (stderr, "*** Starting TLS handshake\n");
956 ret = do_handshake (&hd);
957 if (ret < 0)
959 fprintf (stderr, "*** Handshake has failed\n");
960 user_term = 1;
961 retval = 1;
962 break;
966 inp = check_net_or_keyboard_input(&hd);
968 if (inp == IN_NET)
970 memset (buffer, 0, MAX_BUF + 1);
971 ret = socket_recv (&hd, buffer, MAX_BUF);
973 if (ret == 0)
975 printf ("- Peer has closed the GnuTLS connection\n");
976 break;
978 else if (handle_error (&hd, ret) < 0 && user_term == 0)
980 fprintf (stderr,
981 "*** Server has terminated the connection abnormally.\n");
982 retval = 1;
983 break;
985 else if (ret > 0)
987 if (verbose != 0)
988 printf ("- Received[%d]: ", ret);
989 for (ii = 0; ii < ret; ii++)
991 fputc (buffer[ii], stdout);
993 fflush (stdout);
996 if (user_term != 0)
997 break;
1000 if (inp == IN_KEYBOARD)
1002 if ((bytes = read (fileno (stdin), buffer, MAX_BUF - 1)) <= 0)
1004 if (hd.secure == 0)
1006 /* Warning! Do not touch this text string, it is
1007 used by external programs to search for when
1008 gnutls-cli has reached this point. */
1009 fprintf (stderr, "*** Starting TLS handshake\n");
1010 ret = do_handshake (&hd);
1011 clearerr (stdin);
1012 if (ret < 0)
1014 fprintf (stderr, "*** Handshake has failed\n");
1015 user_term = 1;
1016 retval = 1;
1017 break;
1020 else
1022 user_term = 1;
1023 break;
1025 continue;
1028 buffer[bytes] = 0;
1029 if (crlf != 0)
1031 char *b = strchr (buffer, '\n');
1032 if (b != NULL)
1034 strcpy (b, "\r\n");
1035 bytes++;
1039 ret = socket_send (&hd, buffer, bytes);
1041 if (ret > 0)
1043 if (verbose != 0)
1044 printf ("- Sent: %d bytes\n", ret);
1046 else
1047 handle_error (&hd, ret);
1052 if (user_term != 0)
1053 socket_bye (&hd);
1054 else
1055 gnutls_deinit (hd.session);
1057 #ifdef ENABLE_SRP
1058 if (srp_cred)
1059 gnutls_srp_free_client_credentials (srp_cred);
1060 #endif
1061 #ifdef ENABLE_PSK
1062 if (psk_cred)
1063 gnutls_psk_free_client_credentials (psk_cred);
1064 #endif
1066 gnutls_certificate_free_credentials (xcred);
1068 #ifdef ENABLE_ANON
1069 gnutls_anon_free_client_credentials (anon_cred);
1070 #endif
1072 gnutls_global_deinit ();
1074 return retval;
1077 static void
1078 cmd_parser (int argc, char **argv)
1080 const char* rest = NULL;
1082 int optct = optionProcess( &gnutls_cliOptions, argc, argv);
1083 argc -= optct;
1084 argv += optct;
1086 if (rest == NULL && argc > 0)
1087 rest = argv[0];
1089 if (HAVE_OPT(BENCHMARK_CIPHERS))
1091 benchmark_cipher(1, OPT_VALUE_DEBUG);
1092 exit(0);
1095 if (HAVE_OPT(BENCHMARK_SOFT_CIPHERS))
1097 benchmark_cipher(0, OPT_VALUE_DEBUG);
1098 exit(0);
1101 if (HAVE_OPT(BENCHMARK_TLS_CIPHERS))
1103 benchmark_tls(OPT_VALUE_DEBUG, 1);
1104 exit(0);
1107 if (HAVE_OPT(BENCHMARK_TLS_KX))
1109 benchmark_tls(OPT_VALUE_DEBUG, 0);
1110 exit(0);
1113 if (HAVE_OPT(PRIORITY))
1115 priorities = OPT_ARG(PRIORITY);
1117 verbose = HAVE_OPT( VERBOSE);
1118 if (verbose)
1119 print_cert = 1;
1120 else
1121 print_cert = HAVE_OPT( PRINT_CERT);
1123 if (HAVE_OPT(LIST))
1125 print_list(priorities, verbose);
1126 exit(0);
1129 disable_extensions = HAVE_OPT( DISABLE_EXTENSIONS);
1130 starttls = HAVE_OPT(STARTTLS);
1131 resume = HAVE_OPT(RESUME);
1132 rehandshake = HAVE_OPT(REHANDSHAKE);
1133 insecure = HAVE_OPT(INSECURE);
1135 udp = HAVE_OPT(UDP);
1136 mtu = OPT_VALUE_MTU;
1138 if (HAVE_OPT(PORT))
1140 service = OPT_ARG(PORT);
1142 else
1144 service = "443";
1147 record_max_size = OPT_VALUE_RECORDSIZE;
1148 status_request_ocsp = ENABLED_OPT(OCSP_STATUS_REQUEST);
1149 if (ENABLED_OPT(OCSP))
1150 status_request_ocsp = 1;
1152 fingerprint = HAVE_OPT(FINGERPRINT);
1154 if (HAVE_OPT(X509FMTDER))
1155 x509ctype = GNUTLS_X509_FMT_DER;
1156 else
1157 x509ctype = GNUTLS_X509_FMT_PEM;
1159 if (HAVE_OPT(SRPUSERNAME))
1160 srp_username = OPT_ARG(SRPUSERNAME);
1162 if (HAVE_OPT(SRPPASSWD))
1163 srp_passwd = OPT_ARG(SRPPASSWD);
1165 if (HAVE_OPT(X509CAFILE))
1166 x509_cafile = OPT_ARG(X509CAFILE);
1168 if (HAVE_OPT(X509CRLFILE))
1169 x509_crlfile = OPT_ARG(X509CRLFILE);
1171 if (HAVE_OPT(X509KEYFILE))
1172 x509_keyfile = OPT_ARG(X509KEYFILE);
1174 if (HAVE_OPT(X509CERTFILE))
1175 x509_certfile = OPT_ARG(X509CERTFILE);
1177 if (HAVE_OPT(PGPKEYFILE))
1178 pgp_keyfile = OPT_ARG(PGPKEYFILE);
1180 if (HAVE_OPT(PGPCERTFILE))
1181 pgp_certfile = OPT_ARG(PGPCERTFILE);
1183 if (HAVE_OPT(PSKUSERNAME))
1184 psk_username = OPT_ARG(PSKUSERNAME);
1186 if (HAVE_OPT(PSKKEY))
1188 psk_key.data = (unsigned char *) OPT_ARG(PSKKEY);
1189 psk_key.size = strlen (OPT_ARG(PSKKEY));
1191 else
1192 psk_key.size = 0;
1194 if (HAVE_OPT(PGPKEYRING))
1195 pgp_keyring = OPT_ARG(PGPKEYRING);
1197 crlf = HAVE_OPT(CRLF);
1199 if (rest != NULL)
1200 hostname = rest;
1202 if (hostname == NULL)
1204 fprintf(stderr, "No hostname specified\n");
1205 exit(1);
1209 static void
1210 check_rehandshake (socket_st * socket, int ret)
1212 if (socket->secure && ret == GNUTLS_E_REHANDSHAKE)
1214 /* There is a race condition here. If application
1215 * data is sent after the rehandshake request,
1216 * the server thinks we ignored his request.
1217 * This is a bad design of this client.
1219 printf ("*** Received rehandshake request\n");
1220 /* gnutls_alert_send( session, GNUTLS_AL_WARNING, GNUTLS_A_NO_RENEGOTIATION); */
1222 ret = do_handshake (socket);
1224 if (ret == 0)
1226 printf ("*** Rehandshake was performed.\n");
1228 else
1230 printf ("*** Rehandshake Failed.\n");
1236 static int
1237 do_handshake (socket_st * socket)
1239 int ret;
1241 gnutls_transport_set_ptr (socket->session,
1242 (gnutls_transport_ptr_t)
1243 gl_fd_to_handle (socket->fd));
1246 gnutls_handshake_set_timeout( socket->session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
1247 ret = gnutls_handshake (socket->session);
1249 if (ret < 0)
1251 handle_error (socket, ret);
1254 while (ret < 0 && gnutls_error_is_fatal (ret) == 0);
1256 if (ret == 0)
1258 /* print some information */
1259 print_info (socket->session, verbose, 0);
1260 socket->secure = 1;
1262 else
1264 gnutls_alert_send_appropriate (socket->session, ret);
1265 shutdown (socket->fd, SHUT_RDWR);
1267 return ret;
1270 static int
1271 srp_username_callback (gnutls_session_t session,
1272 char **username, char **password)
1274 if (srp_username == NULL || srp_passwd == NULL)
1276 return -1;
1279 *username = gnutls_strdup (srp_username);
1280 *password = gnutls_strdup (srp_passwd);
1282 return 0;
1285 static int
1286 psk_callback (gnutls_session_t session, char **username, gnutls_datum_t * key)
1288 const char *hint = gnutls_psk_client_get_hint (session);
1289 char *rawkey;
1290 char *passwd;
1291 int ret;
1292 size_t res_size;
1293 gnutls_datum_t tmp;
1295 printf ("- PSK client callback. ");
1296 if (hint)
1297 printf ("PSK hint '%s'\n", hint);
1298 else
1299 printf ("No PSK hint\n");
1301 if (HAVE_OPT(PSKUSERNAME))
1302 *username = gnutls_strdup (OPT_ARG(PSKUSERNAME));
1303 else
1305 char *tmp = NULL;
1306 size_t n;
1308 printf ("Enter PSK identity: ");
1309 fflush (stdout);
1310 getline (&tmp, &n, stdin);
1312 if (tmp == NULL)
1314 fprintf (stderr, "No username given, aborting...\n");
1315 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1318 if (tmp[strlen (tmp) - 1] == '\n')
1319 tmp[strlen (tmp) - 1] = '\0';
1320 if (tmp[strlen (tmp) - 1] == '\r')
1321 tmp[strlen (tmp) - 1] = '\0';
1323 *username = gnutls_strdup (tmp);
1324 free (tmp);
1326 if (!*username)
1327 return GNUTLS_E_MEMORY_ERROR;
1329 passwd = getpass ("Enter key: ");
1330 if (passwd == NULL)
1332 fprintf (stderr, "No key given, aborting...\n");
1333 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1336 tmp.data = (void*)passwd;
1337 tmp.size = strlen (passwd);
1339 res_size = tmp.size / 2 + 1;
1340 rawkey = gnutls_malloc (res_size);
1341 if (rawkey == NULL)
1342 return GNUTLS_E_MEMORY_ERROR;
1344 ret = gnutls_hex_decode (&tmp, rawkey, &res_size);
1345 if (ret < 0)
1347 fprintf (stderr, "Error deriving password: %s\n",
1348 gnutls_strerror (ret));
1349 gnutls_free (*username);
1350 return ret;
1353 key->data = (void*)rawkey;
1354 key->size = res_size;
1356 if (HAVE_OPT(DEBUG))
1358 char hexkey[41];
1359 res_size = sizeof (hexkey);
1360 gnutls_hex_encode (key, hexkey, &res_size);
1361 fprintf (stderr, "PSK username: %s\n", *username);
1362 fprintf (stderr, "PSK hint: %s\n", hint);
1363 fprintf (stderr, "PSK key: %s\n", hexkey);
1366 return 0;
1369 static void
1370 init_global_tls_stuff (void)
1372 int ret;
1374 /* X509 stuff */
1375 if (gnutls_certificate_allocate_credentials (&xcred) < 0)
1377 fprintf (stderr, "Certificate allocation memory error\n");
1378 exit (1);
1380 gnutls_certificate_set_pin_function(xcred, pin_callback, NULL);
1382 if (x509_cafile != NULL)
1384 ret = gnutls_certificate_set_x509_trust_file (xcred,
1385 x509_cafile, x509ctype);
1387 else
1389 ret = gnutls_certificate_set_x509_system_trust (xcred);
1391 if (ret < 0)
1393 fprintf (stderr, "Error setting the x509 trust file\n");
1395 else
1397 printf ("Processed %d CA certificate(s).\n", ret);
1400 if (x509_crlfile != NULL)
1402 ret = gnutls_certificate_set_x509_crl_file (xcred, x509_crlfile,
1403 x509ctype);
1404 if (ret < 0)
1406 fprintf (stderr, "Error setting the x509 CRL file\n");
1408 else
1410 printf ("Processed %d CRL(s).\n", ret);
1414 load_keys ();
1416 #ifdef ENABLE_OPENPGP
1417 if (pgp_keyring != NULL)
1419 ret =
1420 gnutls_certificate_set_openpgp_keyring_file (xcred, pgp_keyring,
1421 GNUTLS_OPENPGP_FMT_BASE64);
1422 if (ret < 0)
1424 fprintf (stderr, "Error setting the OpenPGP keyring file\n");
1427 #endif
1429 #ifdef ENABLE_SRP
1430 if (srp_username && srp_passwd)
1432 /* SRP stuff */
1433 if (gnutls_srp_allocate_client_credentials (&srp_cred) < 0)
1435 fprintf (stderr, "SRP authentication error\n");
1438 gnutls_srp_set_client_credentials_function (srp_cred,
1439 srp_username_callback);
1441 #endif
1443 #ifdef ENABLE_PSK
1444 /* PSK stuff */
1445 if (gnutls_psk_allocate_client_credentials (&psk_cred) < 0)
1447 fprintf (stderr, "PSK authentication error\n");
1450 if (psk_username && psk_key.data)
1452 ret = gnutls_psk_set_client_credentials (psk_cred,
1453 psk_username, &psk_key,
1454 GNUTLS_PSK_KEY_HEX);
1455 if (ret < 0)
1457 fprintf (stderr, "Error setting the PSK credentials: %s\n",
1458 gnutls_strerror (ret));
1461 else
1462 gnutls_psk_set_client_credentials_function (psk_cred, psk_callback);
1463 #endif
1465 #ifdef ENABLE_ANON
1466 /* ANON stuff */
1467 if (gnutls_anon_allocate_client_credentials (&anon_cred) < 0)
1469 fprintf (stderr, "Anonymous authentication error\n");
1471 #endif
1475 /* OCSP check for the peer's certificate. Should be called
1476 * only after the certificate list verication is complete.
1477 * Returns:
1478 * 0: certificate is revoked
1479 * 1: certificate is ok
1480 * -1: dunno
1482 static int
1483 cert_verify_ocsp (gnutls_session_t session)
1485 gnutls_x509_crt_t crt, issuer;
1486 const gnutls_datum_t *cert_list;
1487 unsigned int cert_list_size = 0;
1488 int deinit_issuer = 0;
1489 gnutls_datum_t resp;
1490 int ret;
1492 cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
1493 if (cert_list_size == 0)
1495 fprintf (stderr, "No certificates found!\n");
1496 return -1;
1499 gnutls_x509_crt_init (&crt);
1500 ret =
1501 gnutls_x509_crt_import (crt, &cert_list[0],
1502 GNUTLS_X509_FMT_DER);
1503 if (ret < 0)
1505 fprintf (stderr, "Decoding error: %s\n",
1506 gnutls_strerror (ret));
1507 return -1;
1510 ret = gnutls_certificate_get_issuer(xcred, crt, &issuer, 0);
1511 if (ret < 0 && cert_list_size > 1)
1513 gnutls_x509_crt_init(&issuer);
1514 ret = gnutls_x509_crt_import(issuer, &cert_list[1], GNUTLS_X509_FMT_DER);
1515 if (ret < 0)
1517 fprintf (stderr, "Decoding error: %s\n",
1518 gnutls_strerror (ret));
1519 return -1;
1521 deinit_issuer = 1;
1523 else if (ret < 0)
1525 fprintf(stderr, "Cannot find issuer\n");
1526 ret = -1;
1527 goto cleanup;
1530 ret = send_ocsp_request(NULL, crt, issuer, &resp, 1);
1531 if (ret < 0)
1533 fprintf(stderr, "Cannot contact OCSP server\n");
1534 ret = -1;
1535 goto cleanup;
1538 /* verify and check the response for revoked cert */
1539 ret = check_ocsp_response(crt, issuer, &resp);
1541 cleanup:
1542 if (deinit_issuer)
1543 gnutls_x509_crt_deinit (issuer);
1544 gnutls_x509_crt_deinit (crt);
1546 return ret;