2 * Copyright (C) 2000-2014 Free Software Foundation, Inc.
3 * Copyright (C) 2013-2014 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/>.
26 #include <sys/types.h>
31 #include <sys/socket.h>
35 #include <sys/select.h>
43 #include <gnutls/gnutls.h>
44 #include <gnutls/abstract.h>
45 #include <gnutls/dtls.h>
46 #include <gnutls/x509.h>
47 #include <gnutls/openpgp.h>
48 #include <gnutls/pkcs11.h>
49 #include <gnutls/crypto.h>
51 /* Gnulib portability files. */
52 #include <read-file.h>
57 #include "benchmark.h"
58 #include "inline_cmds.h"
61 #include <gnutls/dane.h>
68 #include <ocsptool-common.h>
72 /* global stuff here */
73 int resume, starttls, insecure, ranges, rehandshake, udp, mtu,
75 const char *hostname = NULL;
76 const char *service = NULL;
80 unsigned int verbose = 0;
83 const char *srp_passwd = NULL;
84 const char *srp_username = NULL;
85 const char *pgp_keyfile = NULL;
86 const char *pgp_certfile = NULL;
87 const char *pgp_keyring = NULL;
88 const char *x509_keyfile = NULL;
89 const char *x509_certfile = NULL;
90 const char *x509_cafile = NULL;
91 const char *x509_crlfile = NULL;
93 static int disable_extensions;
94 static int disable_sni;
95 static unsigned int init_flags = GNUTLS_CLIENT;
96 static const char *priorities = NULL;
97 static const char *inline_commands_prefix;
99 const char *psk_username = NULL;
100 gnutls_datum_t psk_key = { NULL, 0 };
102 static gnutls_srp_client_credentials_t srp_cred;
103 static gnutls_psk_client_credentials_t psk_cred;
104 static gnutls_anon_client_credentials_t anon_cred;
105 static gnutls_certificate_credentials_t xcred;
107 /* end of global stuff */
111 static void check_rehandshake(socket_st * socket, int ret);
112 static int do_handshake(socket_st * socket);
113 static void init_global_tls_stuff(void);
114 static int cert_verify_ocsp(gnutls_session_t session);
117 static unsigned int x509_crt_size;
118 static gnutls_pcert_st x509_crt[MAX_CRT];
119 static gnutls_privkey_t x509_key = NULL;
121 static gnutls_pcert_st pgp_crt;
122 static gnutls_privkey_t pgp_key = NULL;
124 static void get_keyid(gnutls_openpgp_keyid_t keyid, const char *str)
126 size_t keyid_size = GNUTLS_OPENPGP_KEYID_SIZE;
128 if (strlen(str) != 16) {
130 "The OpenPGP subkey ID has to be 16 hexadecimal characters.\n");
134 if (gnutls_hex2bin(str, strlen(str), keyid, &keyid_size) < 0) {
135 fprintf(stderr, "Error converting hex string: %s.\n", str);
142 /* Load the certificate and the private key.
144 static void load_keys(void)
146 unsigned int crt_num;
149 gnutls_datum_t data = { NULL, 0 };
150 gnutls_x509_crt_t crt_list[MAX_CRT];
151 unsigned char keyid[GNUTLS_OPENPGP_KEYID_SIZE];
153 if (x509_certfile != NULL && x509_keyfile != NULL) {
155 if (strncmp(x509_certfile, "pkcs11:", 7) == 0) {
157 gnutls_x509_crt_init(&crt_list[0]);
158 gnutls_x509_crt_set_pin_function(crt_list[0],
163 gnutls_x509_crt_import_pkcs11_url(crt_list[0],
167 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
169 gnutls_x509_crt_import_pkcs11_url
170 (crt_list[0], x509_certfile,
171 GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
175 "*** Error loading cert file.\n");
180 #endif /* ENABLE_PKCS11 */
183 ret = gnutls_load_file(x509_certfile, &data);
186 "*** Error loading cert file.\n");
192 gnutls_x509_crt_list_import(crt_list, &crt_num,
194 GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
196 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
198 "*** Error loading cert file: Too many certs %d\n",
203 "*** Error loading cert file: %s\n",
204 gnutls_strerror(ret));
211 for (i = 0; i < x509_crt_size; i++) {
213 gnutls_pcert_import_x509(&x509_crt[i],
217 "*** Error importing crt to pcert: %s\n",
218 gnutls_strerror(ret));
221 gnutls_x509_crt_deinit(crt_list[i]);
224 gnutls_free(data.data);
226 ret = gnutls_privkey_init(&x509_key);
228 fprintf(stderr, "*** Error initializing key: %s\n",
229 gnutls_strerror(ret));
233 gnutls_privkey_set_pin_function(x509_key, pin_callback,
236 if (gnutls_url_is_supported(x509_keyfile) != 0) {
238 gnutls_privkey_import_url(x509_key,
242 "*** Error loading url: %s\n",
243 gnutls_strerror(ret));
247 ret = gnutls_load_file(x509_keyfile, &data);
250 "*** Error loading key file.\n");
255 gnutls_privkey_import_x509_raw(x509_key, &data,
260 "*** Error loading url: %s\n",
261 gnutls_strerror(ret));
265 gnutls_free(data.data);
269 "Processed %d client X.509 certificates...\n",
273 #ifdef ENABLE_OPENPGP
274 if (HAVE_OPT(PGPSUBKEY)) {
275 get_keyid(keyid, OPT_ARG(PGPSUBKEY));
278 if (pgp_certfile != NULL && pgp_keyfile != NULL) {
279 gnutls_openpgp_crt_t tmp_pgp_crt;
281 ret = gnutls_load_file(pgp_certfile, &data);
284 "*** Error loading PGP cert file.\n");
288 gnutls_openpgp_crt_init(&tmp_pgp_crt);
291 gnutls_pcert_import_openpgp_raw(&pgp_crt, &data,
292 GNUTLS_OPENPGP_FMT_BASE64,
293 HAVE_OPT(PGPSUBKEY) ?
297 "*** Error loading PGP cert file: %s\n",
298 gnutls_strerror(ret));
302 gnutls_free(data.data);
304 ret = gnutls_privkey_init(&pgp_key);
306 fprintf(stderr, "*** Error initializing key: %s\n",
307 gnutls_strerror(ret));
311 gnutls_privkey_set_pin_function(pgp_key, pin_callback,
314 if (gnutls_url_is_supported(pgp_keyfile)) {
316 gnutls_privkey_import_url(pgp_key, pgp_keyfile,
320 "*** Error loading url: %s\n",
321 gnutls_strerror(ret));
325 ret = gnutls_load_file(pgp_keyfile, &data);
328 "*** Error loading key file.\n");
332 if (HAVE_OPT(PGPSUBKEY))
334 gnutls_privkey_import_openpgp_raw
335 (pgp_key, &data, x509ctype, keyid,
339 gnutls_privkey_import_openpgp_raw
340 (pgp_key, &data, x509ctype, NULL,
344 "*** Error loading url: %s\n",
345 gnutls_strerror(ret));
349 gnutls_free(data.data);
353 fprintf(stdout, "Processed 1 client PGP certificate...\n");
359 #define IS_NEWLINE(x) ((x[0] == '\n') || (x[0] == '\r'))
360 static int read_yesno(const char *input_str)
364 fputs(input_str, stderr);
365 if (fgets(input, sizeof(input), stdin) == NULL)
368 if (IS_NEWLINE(input))
371 if (input[0] == 'y' || input[0] == 'Y')
377 static int cert_verify_callback(gnutls_session_t session)
380 unsigned int status = 0;
381 int ssh = ENABLED_OPT(TOFU);
382 int strictssh = ENABLED_OPT(STRICT_TOFU);
384 int dane = ENABLED_OPT(DANE);
386 int ca_verify = ENABLED_OPT(CA_VERIFICATION);
387 const char *txt_service;
389 /* On an session with TOFU the PKI/DANE verification
397 print_cert_info(session, verbose, print_cert);
400 rc = cert_verify(session, hostname, GNUTLS_KP_TLS_WWW_SERVER);
403 ("*** PKI verification of server certificate failed...\n");
404 if (!insecure && !ssh)
406 } else if (ENABLED_OPT(OCSP) && gnutls_ocsp_status_request_is_checked(session, 0) == 0) { /* off-line verification succeeded. Try OCSP */
407 rc = cert_verify_ocsp(session);
410 ("*** Verifying (with OCSP) server certificate failed...\n");
411 if (!insecure && !ssh)
414 printf("*** OCSP response ignored...\n");
419 if (dane) { /* try DANE auth */
422 unsigned int sflags =
423 ENABLED_OPT(LOCAL_DNS) ? 0 :
424 DANE_F_IGNORE_LOCAL_RESOLVER;
426 /* if we didn't verify the chain it only makes sense
427 * to check the end certificate using dane. */
429 vflags |= DANE_VFLAG_ONLY_CHECK_EE_USAGE;
431 port = service_to_port(service, udp?"udp":"tcp");
432 rc = dane_verify_session_crt(NULL, session, hostname,
433 udp ? "udp" : "tcp", port,
434 sflags, vflags, &status);
437 "*** DANE verification error: %s\n",
439 if (!insecure && !ssh)
444 rc = dane_verification_status_print(status, &out,
447 fprintf(stderr, "*** DANE error: %s\n",
450 fprintf(stderr, "- DANE: %s\n", out.data);
451 gnutls_free(out.data);
454 if (status != 0 && !insecure && !ssh)
461 if (ssh) { /* try ssh auth */
462 unsigned int list_size;
463 const gnutls_datum_t *cert;
465 cert = gnutls_certificate_get_peers(session, &list_size);
468 "Cannot obtain peer's certificate!\n");
472 txt_service = port_to_service(service, udp?"udp":"tcp");
474 rc = gnutls_verify_stored_pubkey(NULL, NULL, hostname,
476 GNUTLS_CRT_X509, cert, 0);
477 if (rc == GNUTLS_E_NO_CERTIFICATE_FOUND) {
479 "Host %s (%s) has never been contacted before.\n",
480 hostname, txt_service);
483 "Its certificate is valid for %s.\n",
487 ("Are you sure you want to trust it? (y/N): ");
490 } else if (rc == GNUTLS_E_CERTIFICATE_KEY_MISMATCH) {
492 "Warning: host %s is known and it is associated with a different key.\n",
495 "It might be that the server has multiple keys, or an attacker replaced the key to eavesdrop this connection .\n");
498 "Its certificate is valid for %s.\n",
501 if (strictssh == 0) {
503 ("Do you trust the received key? (y/N): ");
510 "gnutls_verify_stored_pubkey: %s\n",
511 gnutls_strerror(rc));
516 rc = gnutls_store_pubkey(NULL, NULL, hostname,
518 GNUTLS_CRT_X509, cert, 0,
522 "Could not store key: %s\n",
523 gnutls_strerror(rc));
529 /* This callback should be associated with a session by calling
530 * gnutls_certificate_client_set_retrieve_function( session, cert_callback),
531 * before a handshake.
535 cert_callback(gnutls_session_t session,
536 const gnutls_datum_t * req_ca_rdn, int nreqs,
537 const gnutls_pk_algorithm_t * sign_algos,
538 int sign_algos_length, gnutls_pcert_st ** pcert,
539 unsigned int *pcert_length, gnutls_privkey_t * pkey)
542 int i, ret, cert_type;
546 /* Print the server's trusted CAs
549 printf("- Server's trusted authorities:\n");
552 ("- Server did not send us any trusted authorities names.\n");
554 /* print the names (if any) */
555 for (i = 0; i < nreqs; i++) {
556 len = sizeof(issuer_dn);
558 gnutls_x509_rdn_get(&req_ca_rdn[i], issuer_dn,
561 printf(" [%d]: ", i);
562 printf("%s\n", issuer_dn);
567 /* Select a certificate and return it.
568 * The certificate must be of any of the "sign algorithms"
569 * supported by the server.
572 cert_type = gnutls_certificate_type_get(session);
576 if (cert_type == GNUTLS_CRT_X509) {
577 if (x509_crt_size > 0) {
578 if (x509_key != NULL) {
582 ("- Could not find a suitable key to send to server\n");
586 *pcert_length = x509_crt_size;
590 } else if (cert_type == GNUTLS_CRT_OPENPGP) {
591 if (pgp_key != NULL) {
599 printf("- Successfully sent %u certificate(s) to server.\n",
605 /* initializes a gnutls_session_t with some defaults.
607 static gnutls_session_t init_tls_session(const char *host)
612 gnutls_session_t session;
615 gnutls_init(&session, GNUTLS_DATAGRAM | init_flags);
617 gnutls_dtls_set_mtu(session, mtu);
619 gnutls_init(&session, init_flags);
622 gnutls_priority_set_direct(session, priorities, &err)) < 0) {
623 if (ret == GNUTLS_E_INVALID_REQUEST)
624 fprintf(stderr, "Syntax error at: %s\n", err);
626 fprintf(stderr, "Error in priorities: %s\n",
627 gnutls_strerror(ret));
631 /* allow the use of private ciphersuites.
633 if (disable_extensions == 0 && disable_sni == 0) {
634 if (host != NULL && is_ip(host) == 0)
635 gnutls_server_name_set(session, GNUTLS_NAME_DNS,
639 if (HAVE_OPT(DH_BITS))
640 gnutls_dh_set_prime_bits(session, OPT_VALUE_DH_BITS);
642 if (HAVE_OPT(ALPN)) {
643 unsigned proto_n = STACKCT_OPT(ALPN);
644 char **protos = (void *) STACKLST_OPT(ALPN);
645 gnutls_datum_t p[proto_n];
647 for (i = 0; i < proto_n; i++) {
648 p[i].data = (void *) protos[i];
649 p[i].size = strlen(protos[i]);
651 gnutls_alpn_set_protocols(session, p, proto_n, 0);
654 gnutls_credentials_set(session, GNUTLS_CRD_ANON, anon_cred);
656 gnutls_credentials_set(session, GNUTLS_CRD_SRP, srp_cred);
658 gnutls_credentials_set(session, GNUTLS_CRD_PSK, psk_cred);
659 gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred);
661 gnutls_certificate_set_retrieve_function2(xcred, cert_callback);
662 gnutls_certificate_set_verify_function(xcred,
663 cert_verify_callback);
665 /* send the fingerprint */
666 #ifdef ENABLE_OPENPGP
667 if (fingerprint != 0)
668 gnutls_openpgp_send_cert(session,
669 GNUTLS_OPENPGP_CERT_FINGERPRINT);
672 /* use the max record size extension */
673 if (record_max_size > 0 && disable_extensions == 0) {
674 if (gnutls_record_set_max_size(session, record_max_size) <
677 "Cannot set the maximum record size to %d.\n",
680 "Possible values: 512, 1024, 2048, 4096.\n");
685 if (HAVE_OPT(HEARTBEAT))
686 gnutls_heartbeat_enable(session,
687 GNUTLS_HB_PEER_ALLOWED_TO_SEND);
689 #ifdef ENABLE_DTLS_SRTP
690 if (HAVE_OPT(SRTP_PROFILES)) {
692 gnutls_srtp_set_profile_direct(session,
693 OPT_ARG(SRTP_PROFILES),
695 if (ret == GNUTLS_E_INVALID_REQUEST)
696 fprintf(stderr, "Syntax error at: %s\n", err);
698 fprintf(stderr, "Error in profiles: %s\n",
699 gnutls_strerror(ret));
700 else fprintf(stderr,"DTLS profile set to %s\n",
701 OPT_ARG(SRTP_PROFILES));
703 if (ret != 0) exit(1);
711 static void cmd_parser(int argc, char **argv);
713 /* Returns zero if the error code was successfully handled.
715 static int handle_error(socket_st * hd, int err)
718 const char *err_type, *str;
720 if (err >= 0 || err == GNUTLS_E_AGAIN
721 || err == GNUTLS_E_INTERRUPTED)
724 if (gnutls_error_is_fatal(err) == 0) {
726 err_type = "Non fatal";
732 str = gnutls_strerror(err);
735 fprintf(stderr, "*** %s error: %s\n", err_type, str);
737 if (err == GNUTLS_E_WARNING_ALERT_RECEIVED
738 || err == GNUTLS_E_FATAL_ALERT_RECEIVED) {
739 alert = gnutls_alert_get(hd->session);
740 str = gnutls_alert_get_name(alert);
743 printf("*** Received alert [%d]: %s\n", alert, str);
746 check_rehandshake(hd, err);
751 int starttls_alarmed = 0;
754 static void starttls_alarm(int signum)
756 starttls_alarmed = 1;
760 static void tls_log_func(int level, const char *str)
762 fprintf(stderr, "|<%d>| %s", level, str);
765 #define IN_KEYBOARD 1
768 /* returns IN_KEYBOARD for keyboard input and IN_NET for network input
770 static int check_net_or_keyboard_input(socket_st * hd)
779 FD_SET(hd->fd, &rset);
782 FD_SET(fileno(stdin), &rset);
783 maxfd = MAX(fileno(stdin), hd->fd);
789 tv.tv_usec = 50 * 1000;
792 if (gnutls_record_check_pending(hd->session))
795 err = select(maxfd + 1, &rset, NULL, NULL, &tv);
799 if (FD_ISSET(hd->fd, &rset))
806 WaitForSingleObject(GetStdHandle
807 (STD_INPUT_HANDLE), 200);
809 if (state == WAIT_OBJECT_0)
813 if (FD_ISSET(fileno(stdin), &rset))
822 static int try_rehandshake(socket_st * hd)
826 ret = do_handshake(hd);
828 fprintf(stderr, "*** ReHandshake has failed\n");
832 printf("- ReHandshake was completed\n");
837 static int try_resume(socket_st * hd)
842 size_t session_data_size = 0;
844 gnutls_session_get_data(hd->session, NULL, &session_data_size);
845 session_data = (char *) malloc(session_data_size);
846 if (session_data == NULL)
847 return GNUTLS_E_MEMORY_ERROR;
849 gnutls_session_get_data(hd->session, session_data,
852 printf("- Disconnecting\n");
856 ("\n\n- Connecting again- trying to resume previous session\n");
857 socket_open(hd, hostname, service, udp, CONNECT_MSG);
859 if (HAVE_OPT(STARTTLS_PROTO))
860 socket_starttls(hd, OPT_ARG(STARTTLS_PROTO));
862 hd->session = init_tls_session(hostname);
863 gnutls_session_set_data(hd->session, session_data,
867 ret = do_handshake(hd);
869 fprintf(stderr, "*** Resume handshake has failed\n");
874 printf("- Resume Handshake was completed\n");
875 if (gnutls_session_is_resumed(hd->session) != 0)
876 printf("*** This is a resumed session\n");
882 bool parse_for_inline_commands_in_buffer(char *buffer, size_t bytes,
883 inline_cmds_st * inline_cmds)
885 ssize_t local_bytes, match_bytes, prev_bytes_copied, ii, jj;
886 char *local_buffer_ptr, *ptr;
887 char inline_command_string[MAX_INLINE_COMMAND_BYTES];
890 inline_cmds->bytes_to_flush = 0;
891 inline_cmds->cmd_found = INLINE_COMMAND_NONE;
893 if (inline_cmds->bytes_copied) {
895 &inline_cmds->inline_cmd_buffer[inline_cmds->
899 ((inline_cmds->bytes_copied + bytes) <=
900 MAX_INLINE_COMMAND_BYTES) ? (ssize_t) bytes
901 : (MAX_INLINE_COMMAND_BYTES -
902 inline_cmds->bytes_copied);
904 memcpy(local_buffer_ptr, buffer, local_bytes);
905 prev_bytes_copied = inline_cmds->bytes_copied;
906 inline_cmds->new_buffer_ptr = buffer + local_bytes;
907 inline_cmds->bytes_copied += local_bytes;
908 local_buffer_ptr = inline_cmds->inline_cmd_buffer;
909 local_bytes = inline_cmds->bytes_copied;
911 prev_bytes_copied = 0;
912 local_buffer_ptr = buffer;
914 inline_cmds->new_buffer_ptr = buffer + bytes;
917 inline_cmds->current_ptr = local_buffer_ptr;
919 if (local_buffer_ptr[0] == inline_commands_prefix[0]
920 && inline_cmds->lf_found) {
921 for (jj = 0; jj < NUM_INLINE_COMMANDS; jj++) {
922 if (inline_commands_prefix[0] != '^') { /* refer inline_cmds.h for usage of ^ */
923 strcpy(inline_command_string,
924 inline_commands_def[jj].string);
925 inline_command_string[strlen
929 inline_command_string[0] =
930 inline_commands_prefix[0];
931 /* Inline commands are delimited by the inline_commands_prefix[0] (default is ^).
932 The inline_commands_def[].string includes a trailing LF */
933 inline_command_string[strlen
936 inline_commands_prefix[0];
937 ptr = inline_command_string;
939 ptr = inline_commands_def[jj].string;
942 match_bytes = (local_bytes <= l) ? local_bytes : l;
943 if (strncmp(ptr, local_buffer_ptr, match_bytes) ==
945 if (match_bytes == (ssize_t) strlen(ptr)) {
946 inline_cmds->new_buffer_ptr =
947 buffer + match_bytes -
949 inline_cmds->cmd_found =
950 inline_commands_def[jj].
952 inline_cmds->bytes_copied = 0; /* reset it */
954 /* partial command */
955 memcpy(&inline_cmds->
957 [inline_cmds->bytes_copied],
959 inline_cmds->bytes_copied += bytes;
963 /* else - if not a match, do nothing here */
967 for (ii = prev_bytes_copied; ii < local_bytes; ii++) {
968 if (ii && local_buffer_ptr[ii] == inline_commands_prefix[0]
969 && inline_cmds->lf_found) {
970 /* possible inline command. First, let's flush bytes up to ^ */
971 inline_cmds->new_buffer_ptr =
972 buffer + ii - prev_bytes_copied;
973 inline_cmds->bytes_to_flush = ii;
974 inline_cmds->lf_found = true;
976 /* bytes to flush starts at inline_cmds->current_ptr */
978 } else if (local_buffer_ptr[ii] == '\n') {
979 inline_cmds->lf_found = true;
981 inline_cmds->lf_found = false;
985 inline_cmds->bytes_copied = 0; /* reset it */
986 return false; /* not an inline command */
990 int run_inline_command(inline_cmds_st * cmd, socket_st * hd)
992 switch (cmd->cmd_found) {
993 case INLINE_COMMAND_RESUME:
994 return try_resume(hd);
995 case INLINE_COMMAND_RENEGOTIATE:
996 return try_rehandshake(hd);
1003 int do_inline_command_processing(char *buffer_ptr, size_t curr_bytes,
1005 inline_cmds_st * inline_cmds)
1007 int skip_bytes, bytes;
1008 bool inline_cmd_start_found;
1012 continue_inline_processing:
1013 /* parse_for_inline_commands_in_buffer hunts for start of an inline command
1014 * sequence. The function maintains state information in inline_cmds.
1016 inline_cmd_start_found =
1017 parse_for_inline_commands_in_buffer(buffer_ptr, bytes,
1019 if (!inline_cmd_start_found)
1022 /* inline_cmd_start_found is set */
1024 if (inline_cmds->bytes_to_flush) {
1025 /* start of an inline command sequence found, but is not
1026 * at the beginning of buffer. So, we flush all preceding bytes.
1028 return inline_cmds->bytes_to_flush;
1029 } else if (inline_cmds->cmd_found == INLINE_COMMAND_NONE) {
1030 /* partial command found */
1033 /* complete inline command found and is at the start */
1034 if (run_inline_command(inline_cmds, hd))
1037 inline_cmds->cmd_found = INLINE_COMMAND_NONE;
1038 skip_bytes = inline_cmds->new_buffer_ptr - buffer_ptr;
1040 if (skip_bytes >= bytes)
1043 buffer_ptr = inline_cmds->new_buffer_ptr;
1044 bytes -= skip_bytes;
1045 goto continue_inline_processing;
1051 print_other_info(gnutls_session_t session)
1054 gnutls_datum_t oresp;
1056 ret = gnutls_ocsp_status_request_get(session, &oresp);
1062 if (ENABLED_OPT(VERBOSE) && oresp.data) {
1063 gnutls_ocsp_resp_t r;
1067 ret = gnutls_ocsp_resp_init(&r);
1069 fprintf(stderr, "ocsp_resp_init: %s\n",
1070 gnutls_strerror(ret));
1074 ret = gnutls_ocsp_resp_import(r, &oresp);
1076 fprintf(stderr, "importing response: %s\n",
1077 gnutls_strerror(ret));
1081 if (print_cert != 0)
1082 flag = GNUTLS_OCSP_PRINT_FULL;
1084 flag = GNUTLS_OCSP_PRINT_COMPACT;
1086 gnutls_ocsp_resp_print(r, flag, &p);
1087 gnutls_ocsp_resp_deinit(r);
1088 fputs((char*)p.data, stdout);
1091 if (HAVE_OPT(SAVE_OCSP) && oresp.data) {
1092 FILE *fp = fopen(OPT_ARG(SAVE_OCSP), "w");
1095 fwrite(oresp.data, 1, oresp.size, fp);
1101 int main(int argc, char **argv)
1105 char buffer[MAX_BUF + 1];
1106 int user_term = 0, retval = 0;
1108 ssize_t bytes, keyboard_bytes;
1109 char *keyboard_buffer_ptr;
1110 inline_cmds_st inline_cmds;
1112 struct sigaction new_action;
1115 cmd_parser(argc, argv);
1117 gnutls_global_set_log_function(tls_log_func);
1118 gnutls_global_set_log_level(OPT_VALUE_DEBUG);
1120 if ((ret = gnutls_global_init()) < 0) {
1121 fprintf(stderr, "global_init: %s\n", gnutls_strerror(ret));
1125 if (hostname == NULL) {
1126 fprintf(stderr, "No hostname given\n");
1132 init_global_tls_stuff();
1134 socket_open(&hd, hostname, service, udp, CONNECT_MSG);
1135 hd.verbose = verbose;
1137 if (HAVE_OPT(STARTTLS_PROTO))
1138 socket_starttls(&hd, OPT_ARG(STARTTLS_PROTO));
1140 hd.session = init_tls_session(hostname);
1142 goto after_handshake;
1144 ret = do_handshake(&hd);
1147 fprintf(stderr, "*** Handshake has failed\n");
1149 gnutls_deinit(hd.session);
1152 printf("- Handshake was completed\n");
1155 if (try_resume(&hd))
1158 print_other_info(hd.session);
1162 /* Warning! Do not touch this text string, it is used by external
1163 programs to search for when gnutls-cli has reached this point. */
1164 printf("\n- Simple Client Mode:\n\n");
1167 if (try_rehandshake(&hd))
1171 new_action.sa_handler = starttls_alarm;
1172 sigemptyset(&new_action.sa_mask);
1173 new_action.sa_flags = 0;
1175 sigaction(SIGALRM, &new_action, NULL);
1183 setbuf(stdin, NULL);
1185 setbuf(stdout, NULL);
1186 setbuf(stderr, NULL);
1188 if (inline_commands) {
1189 memset(&inline_cmds, 0, sizeof(inline_cmds_st));
1190 inline_cmds.lf_found = true; /* initially, at start of line */
1194 if (starttls_alarmed && !hd.secure) {
1195 /* Warning! Do not touch this text string, it is used by
1196 external programs to search for when gnutls-cli has
1197 reached this point. */
1198 fprintf(stderr, "*** Starting TLS handshake\n");
1199 ret = do_handshake(&hd);
1202 "*** Handshake has failed\n");
1209 inp = check_net_or_keyboard_input(&hd);
1211 if (inp == IN_NET) {
1212 memset(buffer, 0, MAX_BUF + 1);
1213 ret = socket_recv(&hd, buffer, MAX_BUF);
1217 ("- Peer has closed the GnuTLS connection\n");
1219 } else if (handle_error(&hd, ret) < 0
1220 && user_term == 0) {
1222 "*** Server has terminated the connection abnormally.\n");
1225 } else if (ret > 0) {
1227 printf("- Received[%d]: ", ret);
1228 for (ii = 0; ii < ret; ii++) {
1229 fputc(buffer[ii], stdout);
1238 if (inp == IN_KEYBOARD) {
1240 read(fileno(stdin), buffer,
1241 MAX_BUF - 1)) <= 0) {
1242 if (hd.secure == 0) {
1243 /* Warning! Do not touch this text string, it is
1244 used by external programs to search for when
1245 gnutls-cli has reached this point. */
1247 "*** Starting TLS handshake\n");
1248 ret = do_handshake(&hd);
1252 "*** Handshake has failed\n");
1266 char *b = strchr(buffer, '\n');
1273 keyboard_bytes = bytes;
1274 keyboard_buffer_ptr = buffer;
1276 inline_command_processing:
1278 if (inline_commands) {
1280 do_inline_command_processing
1281 (keyboard_buffer_ptr, keyboard_bytes,
1283 if (keyboard_bytes == 0)
1285 else if (keyboard_bytes < 0) { /* error processing an inline command */
1289 /* current_ptr could point to either an inline_cmd_buffer
1290 * or may point to start or an offset into buffer.
1292 keyboard_buffer_ptr =
1293 inline_cmds.current_ptr;
1298 && gnutls_record_can_use_length_hiding(hd.
1301 gnutls_range_st range;
1303 range.high = MAX_BUF;
1305 socket_send_range(&hd,
1306 keyboard_buffer_ptr,
1311 socket_send(&hd, keyboard_buffer_ptr,
1317 printf("- Sent: %d bytes\n", ret);
1319 handle_error(&hd, ret);
1321 if (inline_commands &&
1322 inline_cmds.new_buffer_ptr < (buffer + bytes))
1324 keyboard_buffer_ptr =
1325 inline_cmds.new_buffer_ptr;
1327 (buffer + bytes) - keyboard_buffer_ptr;
1328 goto inline_command_processing;
1336 gnutls_deinit(hd.session);
1340 gnutls_srp_free_client_credentials(srp_cred);
1344 gnutls_psk_free_client_credentials(psk_cred);
1347 gnutls_certificate_free_credentials(xcred);
1350 gnutls_anon_free_client_credentials(anon_cred);
1353 gnutls_global_deinit();
1359 void print_priority_list(void)
1363 unsigned int lineb = 0;
1365 printf("Priority strings in GnuTLS %s:\n", gnutls_check_version(NULL));
1367 fputs("\t", stdout);
1368 for (idx=0;;idx++) {
1369 str = gnutls_priority_string_list(idx, GNUTLS_PRIORITY_LIST_INIT_KEYWORDS);
1372 lineb += printf("%s ", str);
1379 printf("\n\nSpecial strings:\n");
1381 fputs("\t", stdout);
1382 for (idx=0;;idx++) {
1383 str = gnutls_priority_string_list(idx, GNUTLS_PRIORITY_LIST_SPECIAL);
1388 lineb += printf("%%%s ", str);
1399 static void cmd_parser(int argc, char **argv)
1401 const char *rest = NULL;
1403 int optct = optionProcess(&gnutls_cliOptions, argc, argv);
1407 if (rest == NULL && argc > 0)
1411 if (HAVE_OPT(FIPS140_MODE)) {
1412 if (gnutls_fips140_mode_enabled() != 0) {
1413 fprintf(stderr, "library is in FIPS140-2 mode\n");
1416 fprintf(stderr, "library is NOT in FIPS140-2 mode\n");
1420 if (HAVE_OPT(BENCHMARK_CIPHERS)) {
1421 benchmark_cipher(OPT_VALUE_DEBUG);
1425 if (HAVE_OPT(BENCHMARK_TLS_CIPHERS)) {
1426 benchmark_tls(OPT_VALUE_DEBUG, 1);
1430 if (HAVE_OPT(BENCHMARK_TLS_KX)) {
1431 benchmark_tls(OPT_VALUE_DEBUG, 0);
1435 if (HAVE_OPT(PRIORITY)) {
1436 priorities = OPT_ARG(PRIORITY);
1438 verbose = HAVE_OPT(VERBOSE);
1442 print_cert = HAVE_OPT(PRINT_CERT);
1444 if (HAVE_OPT(LIST)) {
1445 print_list(priorities, verbose);
1449 if (HAVE_OPT(PRIORITY_LIST)) {
1450 print_priority_list();
1454 disable_sni = HAVE_OPT(DISABLE_SNI);
1455 disable_extensions = HAVE_OPT(DISABLE_EXTENSIONS);
1456 if (disable_extensions)
1457 init_flags |= GNUTLS_NO_EXTENSIONS;
1459 inline_commands = HAVE_OPT(INLINE_COMMANDS);
1460 if (HAVE_OPT(INLINE_COMMANDS_PREFIX)) {
1461 if (strlen(OPT_ARG(INLINE_COMMANDS_PREFIX)) > 1) {
1463 "inline-commands-prefix value is a single US-ASCII character (octets 0 - 127)\n");
1466 inline_commands_prefix =
1467 (char *) OPT_ARG(INLINE_COMMANDS_PREFIX);
1468 if (!isascii(inline_commands_prefix[0])) {
1470 "inline-commands-prefix value is a single US-ASCII character (octets 0 - 127)\n");
1474 inline_commands_prefix = "^";
1476 starttls = HAVE_OPT(STARTTLS);
1477 resume = HAVE_OPT(RESUME);
1478 rehandshake = HAVE_OPT(REHANDSHAKE);
1479 insecure = HAVE_OPT(INSECURE);
1480 ranges = HAVE_OPT(RANGES);
1482 udp = HAVE_OPT(UDP);
1483 mtu = OPT_VALUE_MTU;
1485 if (HAVE_OPT(PORT)) {
1486 service = OPT_ARG(PORT);
1491 record_max_size = OPT_VALUE_RECORDSIZE;
1493 fingerprint = HAVE_OPT(FINGERPRINT);
1495 if (HAVE_OPT(X509FMTDER))
1496 x509ctype = GNUTLS_X509_FMT_DER;
1498 x509ctype = GNUTLS_X509_FMT_PEM;
1500 if (HAVE_OPT(SRPUSERNAME))
1501 srp_username = OPT_ARG(SRPUSERNAME);
1503 if (HAVE_OPT(SRPPASSWD))
1504 srp_passwd = OPT_ARG(SRPPASSWD);
1506 if (HAVE_OPT(X509CAFILE))
1507 x509_cafile = OPT_ARG(X509CAFILE);
1509 if (HAVE_OPT(X509CRLFILE))
1510 x509_crlfile = OPT_ARG(X509CRLFILE);
1512 if (HAVE_OPT(X509KEYFILE))
1513 x509_keyfile = OPT_ARG(X509KEYFILE);
1515 if (HAVE_OPT(X509CERTFILE))
1516 x509_certfile = OPT_ARG(X509CERTFILE);
1518 if (HAVE_OPT(PGPKEYFILE))
1519 pgp_keyfile = OPT_ARG(PGPKEYFILE);
1521 if (HAVE_OPT(PGPCERTFILE))
1522 pgp_certfile = OPT_ARG(PGPCERTFILE);
1524 if (HAVE_OPT(PSKUSERNAME))
1525 psk_username = OPT_ARG(PSKUSERNAME);
1527 if (HAVE_OPT(PSKKEY)) {
1528 psk_key.data = (unsigned char *) OPT_ARG(PSKKEY);
1529 psk_key.size = strlen(OPT_ARG(PSKKEY));
1533 if (HAVE_OPT(PGPKEYRING))
1534 pgp_keyring = OPT_ARG(PGPKEYRING);
1536 crlf = HAVE_OPT(CRLF);
1541 if (hostname == NULL) {
1542 fprintf(stderr, "No hostname specified\n");
1547 static void check_rehandshake(socket_st * socket, int ret)
1549 if (socket->secure && ret == GNUTLS_E_REHANDSHAKE) {
1550 /* There is a race condition here. If application
1551 * data is sent after the rehandshake request,
1552 * the server thinks we ignored his request.
1553 * This is a bad design of this client.
1555 printf("*** Received rehandshake request\n");
1556 /* gnutls_alert_send( session, GNUTLS_AL_WARNING, GNUTLS_A_NO_RENEGOTIATION); */
1558 ret = do_handshake(socket);
1561 printf("*** Rehandshake was performed.\n");
1563 printf("*** Rehandshake Failed.\n");
1569 static int do_handshake(socket_st * socket)
1573 gnutls_transport_set_int(socket->session, socket->fd);
1574 set_read_funcs(socket->session);
1577 gnutls_handshake_set_timeout(socket->session,
1578 GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
1579 ret = gnutls_handshake(socket->session);
1582 handle_error(socket, ret);
1585 while (ret < 0 && gnutls_error_is_fatal(ret) == 0);
1588 /* print some information */
1589 print_info(socket->session, verbose, 0);
1592 gnutls_alert_send_appropriate(socket->session, ret);
1593 shutdown(socket->fd, SHUT_RDWR);
1599 srp_username_callback(gnutls_session_t session,
1600 char **username, char **password)
1602 if (srp_username == NULL || srp_passwd == NULL) {
1606 *username = gnutls_strdup(srp_username);
1607 *password = gnutls_strdup(srp_passwd);
1613 psk_callback(gnutls_session_t session, char **username,
1614 gnutls_datum_t * key)
1616 const char *hint = gnutls_psk_client_get_hint(session);
1623 printf("- PSK client callback. ");
1625 printf("PSK hint '%s'\n", hint);
1627 printf("No PSK hint\n");
1629 if (HAVE_OPT(PSKUSERNAME))
1630 *username = gnutls_strdup(OPT_ARG(PSKUSERNAME));
1635 printf("Enter PSK identity: ");
1637 getline(&p, &n, stdin);
1641 "No username given, aborting...\n");
1642 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1645 if (p[strlen(p) - 1] == '\n')
1646 p[strlen(p) - 1] = '\0';
1647 if (p[strlen(p) - 1] == '\r')
1648 p[strlen(p) - 1] = '\0';
1650 *username = gnutls_strdup(p);
1654 return GNUTLS_E_MEMORY_ERROR;
1656 passwd = getpass("Enter key: ");
1657 if (passwd == NULL) {
1658 fprintf(stderr, "No key given, aborting...\n");
1659 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1662 tmp.data = (void *) passwd;
1663 tmp.size = strlen(passwd);
1665 res_size = tmp.size / 2 + 1;
1666 rawkey = gnutls_malloc(res_size);
1668 return GNUTLS_E_MEMORY_ERROR;
1670 ret = gnutls_hex_decode(&tmp, rawkey, &res_size);
1672 fprintf(stderr, "Error deriving password: %s\n",
1673 gnutls_strerror(ret));
1674 gnutls_free(*username);
1678 key->data = (void *) rawkey;
1679 key->size = res_size;
1681 if (HAVE_OPT(DEBUG)) {
1683 res_size = sizeof(hexkey);
1684 gnutls_hex_encode(key, hexkey, &res_size);
1685 fprintf(stderr, "PSK username: %s\n", *username);
1686 fprintf(stderr, "PSK hint: %s\n", hint);
1687 fprintf(stderr, "PSK key: %s\n", hexkey);
1693 static void init_global_tls_stuff(void)
1697 #ifdef ENABLE_PKCS11
1698 if (HAVE_OPT(PROVIDER)) {
1699 ret = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, NULL);
1701 fprintf(stderr, "pkcs11_init: %s",
1702 gnutls_strerror(ret));
1705 gnutls_pkcs11_add_provider(OPT_ARG(PROVIDER),
1708 fprintf(stderr, "pkcs11_add_provider: %s",
1709 gnutls_strerror(ret));
1717 if (gnutls_certificate_allocate_credentials(&xcred) < 0) {
1718 fprintf(stderr, "Certificate allocation memory error\n");
1721 gnutls_certificate_set_pin_function(xcred, pin_callback, NULL);
1723 if (x509_cafile != NULL) {
1724 ret = gnutls_certificate_set_x509_trust_file(xcred,
1728 if (insecure == 0) {
1729 ret = gnutls_certificate_set_x509_system_trust(xcred);
1735 fprintf(stderr, "Error setting the x509 trust file\n");
1737 printf("Processed %d CA certificate(s).\n", ret);
1740 if (x509_crlfile != NULL) {
1742 gnutls_certificate_set_x509_crl_file(xcred,
1747 "Error setting the x509 CRL file\n");
1749 printf("Processed %d CRL(s).\n", ret);
1755 #ifdef ENABLE_OPENPGP
1756 if (pgp_keyring != NULL) {
1758 gnutls_certificate_set_openpgp_keyring_file(xcred,
1760 GNUTLS_OPENPGP_FMT_BASE64);
1763 "Error setting the OpenPGP keyring file\n");
1769 if (srp_username && srp_passwd) {
1771 if (gnutls_srp_allocate_client_credentials(&srp_cred) < 0) {
1772 fprintf(stderr, "SRP authentication error\n");
1775 gnutls_srp_set_client_credentials_function(srp_cred,
1776 srp_username_callback);
1782 if (gnutls_psk_allocate_client_credentials(&psk_cred) < 0) {
1783 fprintf(stderr, "PSK authentication error\n");
1786 if (psk_username && psk_key.data) {
1787 ret = gnutls_psk_set_client_credentials(psk_cred,
1790 GNUTLS_PSK_KEY_HEX);
1793 "Error setting the PSK credentials: %s\n",
1794 gnutls_strerror(ret));
1797 gnutls_psk_set_client_credentials_function(psk_cred,
1803 if (gnutls_anon_allocate_client_credentials(&anon_cred) < 0) {
1804 fprintf(stderr, "Anonymous authentication error\n");
1810 /* OCSP check for the peer's certificate. Should be called
1811 * only after the certificate list verication is complete.
1813 * 0: certificate is revoked
1814 * 1: certificate is ok
1817 static int cert_verify_ocsp(gnutls_session_t session)
1819 gnutls_x509_crt_t crt, issuer;
1820 const gnutls_datum_t *cert_list;
1821 unsigned int cert_list_size = 0;
1822 int deinit_issuer = 0;
1823 gnutls_datum_t resp;
1824 unsigned char noncebuf[23];
1825 gnutls_datum_t nonce = { noncebuf, sizeof(noncebuf) };
1828 cert_list = gnutls_certificate_get_peers(session, &cert_list_size);
1829 if (cert_list_size == 0) {
1830 fprintf(stderr, "No certificates found!\n");
1834 gnutls_x509_crt_init(&crt);
1836 gnutls_x509_crt_import(crt, &cert_list[0],
1837 GNUTLS_X509_FMT_DER);
1839 fprintf(stderr, "Decoding error: %s\n",
1840 gnutls_strerror(ret));
1844 ret = gnutls_certificate_get_issuer(xcred, crt, &issuer, 0);
1845 if (ret < 0 && cert_list_size > 1) {
1846 gnutls_x509_crt_init(&issuer);
1848 gnutls_x509_crt_import(issuer, &cert_list[1],
1849 GNUTLS_X509_FMT_DER);
1851 fprintf(stderr, "Decoding error: %s\n",
1852 gnutls_strerror(ret));
1856 } else if (ret < 0) {
1857 fprintf(stderr, "Cannot find issuer\n");
1863 gnutls_rnd(GNUTLS_RND_NONCE, nonce.data, nonce.size);
1865 fprintf(stderr, "gnutls_rnd: %s",
1866 gnutls_strerror(ret));
1871 ret = send_ocsp_request(NULL, crt, issuer, &resp, &nonce);
1873 fprintf(stderr, "Cannot contact OCSP server\n");
1878 /* verify and check the response for revoked cert */
1879 ret = check_ocsp_response(crt, issuer, &resp, &nonce);
1883 gnutls_x509_crt_deinit(issuer);
1884 gnutls_x509_crt_deinit(crt);