Esempio n. 1
0
int ne_sock_sessid(ne_socket *sock, unsigned char *buf, size_t *buflen)
{
#ifdef NE_HAVE_SSL
#ifdef HAVE_GNUTLS
    if (sock->ssl) {
        return gnutls_session_get_id(sock->ssl, buf, buflen);
    } else {
        return -1;
    }
#else
    SSL_SESSION *sess;

    if (!sock->ssl) {
        return -1;
    }

    sess = SSL_get0_session(sock->ssl);

    if (!buf) {
        *buflen = sess->session_id_length;
        return 0;
    }

    if (*buflen < sess->session_id_length) {
        return -1;
    }

    memcpy(buf, sess->session_id, *buflen);
    *buflen = sess->session_id_length;
    return 0;
#endif
#else
    return -1;
#endif
}
Esempio n. 2
0
int
do_handshake (gnutls_session session)
{
  int ret, alert;

  do
    {
      ret = gnutls_handshake (session);
    }
  while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);

  handshake_output = ret;

  if (ret < 0 && verbose > 1)
    {
      if (ret == GNUTLS_E_WARNING_ALERT_RECEIVED
	  || ret == GNUTLS_E_FATAL_ALERT_RECEIVED)
	{
	  alert = gnutls_alert_get (session);
	  printf ("\n");
	  printf ("*** Received alert [%d]: %s\n",
		  alert, gnutls_alert_get_name (alert));
	}
    }

  if (ret < 0)
    return TEST_FAILED;

  gnutls_session_get_data (session, NULL, &session_data_size);

  if (sfree != 0)
    {
      free (session_data);
      sfree = 0;
    }
  session_data = malloc (session_data_size);
  sfree = 1;
  if (session_data == NULL)
    {
      fprintf (stderr, "Memory error\n");
      exit (1);
    }
  gnutls_session_get_data (session, session_data, &session_data_size);

  session_id_size = sizeof (session_id);
  gnutls_session_get_id (session, session_id, &session_id_size);

  return TEST_SUCCEED;
}
Esempio n. 3
0
test_code_t
test_session_resume2 (gnutls_session session)
{
  int ret;
  char tmp_session_id[32];
  int tmp_session_id_size;

  if (session == NULL)
    return TEST_IGNORE;

  ADD_ALL_CIPHERS (session);
  ADD_ALL_COMP (session);
  ADD_ALL_CERTTYPES (session);
  ADD_ALL_PROTOCOLS (session);
  ADD_ALL_MACS (session);
  ADD_ALL_KX (session);

  gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
  gnutls_credentials_set (session, GNUTLS_CRD_ANON, anon_cred);

  gnutls_session_set_data (session, session_data, session_data_size);

  memcpy (tmp_session_id, session_id, session_id_size);
  tmp_session_id_size = session_id_size;

  ret = do_handshake (session);
  if (ret == TEST_FAILED)
    return ret;

  /* check if we actually resumed the previous session */

  session_id_size = sizeof (session_id);
  gnutls_session_get_id (session, session_id, &session_id_size);

  if (session_id_size == 0)
    return TEST_FAILED;

  if (gnutls_session_is_resumed (session))
    return TEST_SUCCEED;

  if (tmp_session_id_size == session_id_size &&
      memcmp (tmp_session_id, session_id, tmp_session_id_size) == 0)
    return TEST_SUCCEED;
  else
    return TEST_FAILED;
}
Esempio n. 4
0
test_code_t
test_session_resume2 (gnutls_session_t session)
{
  int ret;
  char tmp_session_id[32];
  size_t tmp_session_id_size;

  if (session == NULL)
    return TEST_IGNORE;

  sprintf (prio_str,
           INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" ALL_MACS
           ":" ALL_KX ":%s", protocol_str, rest);
  _gnutls_priority_set_direct (session, prio_str);

  gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
  gnutls_credentials_set (session, GNUTLS_CRD_ANON, anon_cred);

  gnutls_session_set_data (session, session_data, session_data_size);

  memcpy (tmp_session_id, session_id, session_id_size);
  tmp_session_id_size = session_id_size;

  ret = do_handshake (session);
  if (ret == TEST_FAILED)
    return ret;

  /* check if we actually resumed the previous session */

  session_id_size = sizeof (session_id);
  gnutls_session_get_id (session, session_id, &session_id_size);

  if (session_id_size == 0)
    return TEST_FAILED;

  if (gnutls_session_is_resumed (session))
    return TEST_SUCCEED;

  if (tmp_session_id_size == session_id_size &&
      memcmp (tmp_session_id, session_id, tmp_session_id_size) == 0)
    return TEST_SUCCEED;
  else
    return TEST_FAILED;
}
Esempio n. 5
0
int
print_info (gnutls_session_t session, int print_cert)
{
    const char *tmp;
    gnutls_credentials_type_t cred;
    gnutls_kx_algorithm_t kx;
    unsigned char session_id[33];
    size_t session_id_size = sizeof (session_id);

    /* print session ID */
    gnutls_session_get_id (session, session_id, &session_id_size);
    printf ("- Session ID: %s\n",
            raw_to_string (session_id, session_id_size));

    /* print the key exchange's algorithm name
     */
    kx = gnutls_kx_get (session);

    cred = gnutls_auth_get_type (session);
    switch (cred)
      {
#ifdef ENABLE_ANON
      case GNUTLS_CRD_ANON:
          if (kx == GNUTLS_KX_ANON_ECDH)
              print_ecdh_info (session, "Anonymous ");
          else
              print_dh_info (session, "Anonymous ", verbose);
          break;
#endif
#ifdef ENABLE_SRP
      case GNUTLS_CRD_SRP:
          /* This should be only called in server
           * side.
           */
          if (gnutls_srp_server_get_username (session) != NULL)
              printf ("- SRP authentication. Connected as '%s'\n",
                      gnutls_srp_server_get_username (session));
          break;
#endif
#ifdef ENABLE_PSK
      case GNUTLS_CRD_PSK:
          /* This returns NULL in server side.
           */
          if (gnutls_psk_client_get_hint (session) != NULL)
              printf ("- PSK authentication. PSK hint '%s'\n",
                      gnutls_psk_client_get_hint (session));
          /* This returns NULL in client side.
           */
          if (gnutls_psk_server_get_username (session) != NULL)
              printf ("- PSK authentication. Connected as '%s'\n",
                      gnutls_psk_server_get_username (session));
          if (kx == GNUTLS_KX_DHE_PSK)
              print_dh_info (session, "Ephemeral ", verbose);
          if (kx == GNUTLS_KX_ECDHE_PSK)
              print_ecdh_info (session, "Ephemeral ");
          break;
#endif
      case GNUTLS_CRD_IA:
          printf ("- TLS/IA authentication\n");
          break;
      case GNUTLS_CRD_CERTIFICATE:
          {
              char dns[256];
              size_t dns_size = sizeof (dns);
              unsigned int type;

              /* This fails in client side */
              if (gnutls_server_name_get
                  (session, dns, &dns_size, &type, 0) == 0)
                {
                    printf ("- Given server name[%d]: %s\n", type, dns);
                }
          }

          print_cert_info (session, 
                           verbose?GNUTLS_CRT_PRINT_FULL:GNUTLS_CRT_PRINT_COMPACT, 
                           print_cert);

          if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS)
              print_dh_info (session, "Ephemeral ", verbose);
          else if (kx == GNUTLS_KX_ECDHE_RSA
                   || kx == GNUTLS_KX_ECDHE_ECDSA)
              print_ecdh_info (session, "Ephemeral ");
      }

    tmp =
        SU (gnutls_protocol_get_name
            (gnutls_protocol_get_version (session)));
    printf ("- Version: %s\n", tmp);

    tmp = SU (gnutls_kx_get_name (kx));
    printf ("- Key Exchange: %s\n", tmp);

    tmp = SU (gnutls_cipher_get_name (gnutls_cipher_get (session)));
    printf ("- Cipher: %s\n", tmp);

    tmp = SU (gnutls_mac_get_name (gnutls_mac_get (session)));
    printf ("- MAC: %s\n", tmp);

    tmp =
        SU (gnutls_compression_get_name
            (gnutls_compression_get (session)));
    printf ("- Compression: %s\n", tmp);

    if (verbose)
      {
          gnutls_datum_t cb;
          int rc;

          rc = gnutls_session_channel_binding (session,
                                               GNUTLS_CB_TLS_UNIQUE, &cb);
          if (rc)
              fprintf (stderr, "Channel binding error: %s\n",
                       gnutls_strerror (rc));
          else
            {
                size_t i;

                printf ("- Channel binding 'tls-unique': ");
                for (i = 0; i < cb.size; i++)
                    printf ("%02x", cb.data[i]);
                printf ("\n");
            }
      }

    /* Warning: Do not print anything more here. The 'Compression:'
       output MUST be the last non-verbose output.  This is used by
       Emacs starttls.el code. */

    fflush (stdout);

    return 0;
}
Esempio n. 6
0
int
main (int argc, char **argv)
{
  int err, ret;
  int ii, i;
  char buffer[MAX_BUF + 1];
  char *session_data = NULL;
  char *session_id = NULL;
  size_t session_data_size;
  size_t session_id_size;
  fd_set rset;
  int maxfd;
  struct timeval tv;
  int user_term = 0, retval = 0;
  socket_st hd;
  ssize_t bytes;

  set_program_name (argv[0]);

  gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);

#ifdef gcry_fips_mode_active
  /* Libgcrypt manual says that gcry_version_check must be called
     before calling gcry_fips_mode_active. */
  gcry_check_version (NULL);
  if (gcry_fips_mode_active ())
    {
      ret = gnutls_register_md5_handler ();
      if (ret)
	fprintf (stderr, "gnutls_register_md5_handler: %s\n",
		 gnutls_strerror (ret));
    }
#endif

  if ((ret = gnutls_global_init ()) < 0)
    {
      fprintf (stderr, "global_init: %s\n", gnutls_strerror (ret));
      exit (1);
    }

  if ((ret = gnutls_global_init_extra ()) < 0)
    {
      fprintf (stderr, "global_init_extra: %s\n", gnutls_strerror (ret));
      exit (1);
    }

  gaa_parser (argc, argv);
  if (hostname == NULL)
    {
      fprintf (stderr, "No hostname given\n");
      exit (1);
    }

  gnutls_global_set_log_function (tls_log_func);
  gnutls_global_set_log_level (info.debug);

  sockets_init ();

#ifndef _WIN32
  signal (SIGPIPE, SIG_IGN);
#endif

  init_global_tls_stuff ();

  socket_open (&hd, hostname, service);
  socket_connect (&hd);

  hd.session = init_tls_session (hostname);
  if (starttls)
    goto after_handshake;

  for (i = 0; i < 2; i++)
    {


      if (i == 1)
	{
	  hd.session = init_tls_session (hostname);
	  gnutls_session_set_data (hd.session, session_data,
				   session_data_size);
	  free (session_data);
	}

      ret = do_handshake (&hd);

      if (ret < 0)
	{
	  fprintf (stderr, "*** Handshake has failed\n");
	  gnutls_perror (ret);
	  gnutls_deinit (hd.session);
	  return 1;
	}
      else
	{
	  printf ("- Handshake was completed\n");
	  if (gnutls_session_is_resumed (hd.session) != 0)
	    printf ("*** This is a resumed session\n");
	}

      if (resume != 0 && i == 0)
	{

	  gnutls_session_get_data (hd.session, NULL, &session_data_size);
	  session_data = malloc (session_data_size);

	  gnutls_session_get_data (hd.session, session_data,
				   &session_data_size);

	  gnutls_session_get_id (hd.session, NULL, &session_id_size);
	  session_id = malloc (session_id_size);
	  gnutls_session_get_id (hd.session, session_id, &session_id_size);

	  /* print some information */
	  print_info (hd.session, hostname, info.insecure);

	  printf ("- Disconnecting\n");
	  socket_bye (&hd);

	  printf
	    ("\n\n- Connecting again- trying to resume previous session\n");
	  socket_open (&hd, hostname, service);
	  socket_connect (&hd);
	}
      else
	{
	  break;
	}
    }

after_handshake:

  /* Warning!  Do not touch this text string, it is used by external
     programs to search for when gnutls-cli has reached this point. */
  printf ("\n- Simple Client Mode:\n\n");

  if (rehandshake)
    {
      ret = do_handshake (&hd);

      if (ret < 0)
	{
	  fprintf (stderr, "*** ReHandshake has failed\n");
	  gnutls_perror (ret);
	  gnutls_deinit (hd.session);
	  return 1;
	}
      else
	{
	  printf ("- ReHandshake was completed\n");
	}
    }

#ifndef _WIN32
  signal (SIGALRM, &starttls_alarm);
#endif

  fflush(stdout);
  fflush(stderr);

  /* do not buffer */
#if !(defined _WIN32 || defined __WIN32__)
  setbuf (stdin, NULL);
#endif
  setbuf (stdout, NULL);
  setbuf (stderr, NULL);

  for (;;)
    {
      if (starttls_alarmed && !hd.secure)
	{
	  /* Warning!  Do not touch this text string, it is used by
	     external programs to search for when gnutls-cli has
	     reached this point. */
	  fprintf (stderr, "*** Starting TLS handshake\n");
	  ret = do_handshake (&hd);
	  if (ret < 0)
	    {
	      fprintf (stderr, "*** Handshake has failed\n");
	      user_term = 1;
	      retval = 1;
	      break;
	    }
	}

      FD_ZERO (&rset);
      FD_SET (fileno (stdin), &rset);
      FD_SET (hd.fd, &rset);

      maxfd = MAX (fileno (stdin), hd.fd);
      tv.tv_sec = 3;
      tv.tv_usec = 0;

      err = select (maxfd + 1, &rset, NULL, NULL, &tv);
      if (err < 0)
	continue;

      if (FD_ISSET (hd.fd, &rset))
	{
	  memset (buffer, 0, MAX_BUF + 1);
	  ret = socket_recv (&hd, buffer, MAX_BUF);

	  if (ret == 0)
	    {
	      printf ("- Peer has closed the GnuTLS connection\n");
	      break;
	    }
	  else if (handle_error (&hd, ret) < 0 && user_term == 0)
	    {
	      fprintf (stderr,
		       "*** Server has terminated the connection abnormally.\n");
	      retval = 1;
	      break;
	    }
	  else if (ret > 0)
	    {
	      if (verbose != 0)
		printf ("- Received[%d]: ", ret);
	      for (ii = 0; ii < ret; ii++)
		{
		  fputc (buffer[ii], stdout);
		}
	      fflush (stdout);
	    }

	  if (user_term != 0)
	    break;
	}

      if (FD_ISSET (fileno (stdin), &rset))
	{
	  if ((bytes = read (fileno (stdin), buffer, MAX_BUF - 1)) <= 0)
	    {
	      if (hd.secure == 0)
		{
		  /* Warning!  Do not touch this text string, it is
		     used by external programs to search for when
		     gnutls-cli has reached this point. */
		  fprintf (stderr, "*** Starting TLS handshake\n");
		  ret = do_handshake (&hd);
		  clearerr (stdin);
		  if (ret < 0)
		    {
		      fprintf (stderr, "*** Handshake has failed\n");
		      user_term = 1;
		      retval = 1;
		      break;
		    }
		}
	      else
		{
		  user_term = 1;
		  break;
		}
	      continue;
	    }

	  if (crlf != 0)
	    {
	      char *b = strchr (buffer, '\n');
	      if (b != NULL)
		{
		  strcpy (b, "\r\n");
		  bytes++;
		}
	    }

	  ret = socket_send (&hd, buffer, bytes);

	  if (ret > 0)
	    {
	      if (verbose != 0)
		printf ("- Sent: %d bytes\n", ret);
	    }
	  else
	    handle_error (&hd, ret);

	}
    }

  if (info.debug)
    gcry_control (GCRYCTL_DUMP_RANDOM_STATS);

  if (user_term != 0)
    socket_bye (&hd);
  else
    gnutls_deinit (hd.session);

#ifdef ENABLE_SRP
  if (srp_cred)
    gnutls_srp_free_client_credentials (srp_cred);
#endif
#ifdef ENABLE_PSK
  if (psk_cred)
    gnutls_psk_free_client_credentials (psk_cred);
#endif

  gnutls_certificate_free_credentials (xcred);

#ifdef ENABLE_ANON
  gnutls_anon_free_client_credentials (anon_cred);
#endif

  gnutls_global_deinit ();

  return retval;
}
Esempio n. 7
0
int
main (int argc, char **argv)
{
  int ret;
  int ii, i, inp;
  char buffer[MAX_BUF + 1];
  char *session_data = NULL;
  char *session_id = NULL;
  size_t session_data_size;
  size_t session_id_size = 0;
  int user_term = 0, retval = 0;
  socket_st hd;
  ssize_t bytes;

  set_program_name (argv[0]);
  gaa_parser (argc, argv);

  gnutls_global_set_log_function (tls_log_func);
  gnutls_global_set_log_level (info.debug);

  if ((ret = gnutls_global_init ()) < 0)
    {
      fprintf (stderr, "global_init: %s\n", gnutls_strerror (ret));
      exit (1);
    }

#ifdef ENABLE_PKCS11
  pkcs11_common ();
#endif

  if (hostname == NULL)
    {
      fprintf (stderr, "No hostname given\n");
      exit (1);
    }

  sockets_init ();

#ifndef _WIN32
  signal (SIGPIPE, SIG_IGN);
#endif

  init_global_tls_stuff ();

  socket_open (&hd, hostname, service);
  socket_connect (&hd);

  hd.session = init_tls_session (hostname);
  if (starttls)
    goto after_handshake;

  for (i = 0; i < 2; i++)
    {


      if (i == 1)
        {
          hd.session = init_tls_session (hostname);
          gnutls_session_set_data (hd.session, session_data,
                                   session_data_size);
          free (session_data);
        }

      ret = do_handshake (&hd);

      if (ret < 0)
        {
          fprintf (stderr, "*** Handshake has failed\n");
          gnutls_perror (ret);
          gnutls_deinit (hd.session);
          return 1;
        }
      else
        {
          printf ("- Handshake was completed\n");
          if (gnutls_session_is_resumed (hd.session) != 0)
            printf ("*** This is a resumed session\n");
        }

      if (resume != 0 && i == 0)
        {

          gnutls_session_get_data (hd.session, NULL, &session_data_size);
          session_data = malloc (session_data_size);

          gnutls_session_get_data (hd.session, session_data,
                                   &session_data_size);

          gnutls_session_get_id (hd.session, NULL, &session_id_size);

          session_id = malloc (session_id_size);
          gnutls_session_get_id (hd.session, session_id, &session_id_size);

          /* print some information */
          print_info (hd.session, hostname, info.insecure);

          printf ("- Disconnecting\n");
          socket_bye (&hd);

          printf
            ("\n\n- Connecting again- trying to resume previous session\n");
          socket_open (&hd, hostname, service);
          socket_connect (&hd);
        }
      else
        {
          break;
        }
    }

after_handshake:

  /* Warning!  Do not touch this text string, it is used by external
     programs to search for when gnutls-cli has reached this point. */
  printf ("\n- Simple Client Mode:\n\n");

  if (rehandshake)
    {
      ret = do_handshake (&hd);

      if (ret < 0)
        {
          fprintf (stderr, "*** ReHandshake has failed\n");
          gnutls_perror (ret);
          gnutls_deinit (hd.session);
          return 1;
        }
      else
        {
          printf ("- ReHandshake was completed\n");
        }
    }

#ifndef _WIN32
  signal (SIGALRM, &starttls_alarm);
#endif

  fflush (stdout);
  fflush (stderr);

  /* do not buffer */
#if !(defined _WIN32 || defined __WIN32__)
  setbuf (stdin, NULL);
#endif
  setbuf (stdout, NULL);
  setbuf (stderr, NULL);

  for (;;)
    {
      if (starttls_alarmed && !hd.secure)
        {
          /* Warning!  Do not touch this text string, it is used by
             external programs to search for when gnutls-cli has
             reached this point. */
          fprintf (stderr, "*** Starting TLS handshake\n");
          ret = do_handshake (&hd);
          if (ret < 0)
            {
              fprintf (stderr, "*** Handshake has failed\n");
              user_term = 1;
              retval = 1;
              break;
            }
        }

      inp = check_net_or_keyboard_input(&hd);

      if (inp == IN_NET)
        {
          memset (buffer, 0, MAX_BUF + 1);
          ret = socket_recv (&hd, buffer, MAX_BUF);

          if (ret == 0)
            {
              printf ("- Peer has closed the GnuTLS connection\n");
              break;
            }
          else if (handle_error (&hd, ret) < 0 && user_term == 0)
            {
              fprintf (stderr,
                       "*** Server has terminated the connection abnormally.\n");
              retval = 1;
              break;
            }
          else if (ret > 0)
            {
              if (verbose != 0)
                printf ("- Received[%d]: ", ret);
              for (ii = 0; ii < ret; ii++)
                {
                  fputc (buffer[ii], stdout);
                }
              fflush (stdout);
            }

          if (user_term != 0)
            break;
        }

      if (inp == IN_KEYBOARD)
        {
          if ((bytes = read (fileno (stdin), buffer, MAX_BUF - 1)) <= 0)
            {
              if (hd.secure == 0)
                {
                  /* Warning!  Do not touch this text string, it is
                     used by external programs to search for when
                     gnutls-cli has reached this point. */
                  fprintf (stderr, "*** Starting TLS handshake\n");
                  ret = do_handshake (&hd);
                  clearerr (stdin);
                  if (ret < 0)
                    {
                      fprintf (stderr, "*** Handshake has failed\n");
                      user_term = 1;
                      retval = 1;
                      break;
                    }
                }
              else
                {
                  user_term = 1;
                  break;
                }
              continue;
            }

          buffer[bytes] = 0;
          if (crlf != 0)
            {
              char *b = strchr (buffer, '\n');
              if (b != NULL)
                {
                  strcpy (b, "\r\n");
                  bytes++;
                }
            }

          ret = socket_send (&hd, buffer, bytes);

          if (ret > 0)
            {
              if (verbose != 0)
                printf ("- Sent: %d bytes\n", ret);
            }
          else
            handle_error (&hd, ret);

        }
    }

  if (user_term != 0)
    socket_bye (&hd);
  else
    gnutls_deinit (hd.session);

#ifdef ENABLE_SRP
  if (srp_cred)
    gnutls_srp_free_client_credentials (srp_cred);
#endif
#ifdef ENABLE_PSK
  if (psk_cred)
    gnutls_psk_free_client_credentials (psk_cred);
#endif

  gnutls_certificate_free_credentials (xcred);

#ifdef ENABLE_ANON
  gnutls_anon_free_client_credentials (anon_cred);
#endif

  gnutls_global_deinit ();

  return retval;
}
Esempio n. 8
0
int
main (int argc, char **argv)
{
  int err, ret;
  int ii, i;
  char buffer[MAX_BUF + 1];
  char *session_data = NULL;
  char *session_id = NULL;
  size_t session_data_size;
  size_t session_id_size;
  fd_set rset;
  int maxfd;
  struct timeval tv;
  int user_term = 0;
  socket_st hd;

  gaa_parser (argc, argv);
  if (hostname == NULL)
    {
      fprintf (stderr, "No hostname given\n");
      exit (1);
    }

  sockets_init ();

#ifndef _WIN32
  signal (SIGPIPE, SIG_IGN);
#endif

  init_global_tls_stuff ();

  socket_open( &hd, hostname, service);
  socket_connect( &hd);

  hd.session = init_tls_session (hostname);
  if (starttls)
    goto after_handshake;

  for (i = 0; i < 2; i++)
    {


      if (i == 1)
	{
	  hd.session = init_tls_session (hostname);
	  gnutls_session_set_data (hd.session, session_data,
				   session_data_size);
	  free (session_data);
	}

      ret = do_handshake (&hd);

      if (ret < 0)
	{
	  fprintf (stderr, "*** Handshake has failed\n");
	  gnutls_perror (ret);
	  gnutls_deinit (hd.session);
	  return 1;
	}
      else
	{
	  printf ("- Handshake was completed\n");
	  if (gnutls_session_is_resumed (hd.session) != 0)
	    printf ("*** This is a resumed session\n");
	}



      if (resume != 0 && i == 0)
	{

	  gnutls_session_get_data (hd.session, NULL, &session_data_size);
	  session_data = malloc (session_data_size);

	  gnutls_session_get_data (hd.session, session_data,
				   &session_data_size);

	  gnutls_session_get_id (hd.session, NULL, &session_id_size);
	  session_id = malloc (session_id_size);
	  gnutls_session_get_id (hd.session, session_id, &session_id_size);

	  /* print some information */
	  print_info (hd.session, hostname);

	  printf ("- Disconnecting\n");
	  socket_bye (&hd);

	  printf
	    ("\n\n- Connecting again- trying to resume previous session\n");
          socket_open( &hd, hostname, service);
          socket_connect(&hd);
	}
      else
	{
	  break;
	}
    }

after_handshake:

  printf ("\n- Simple Client Mode:\n\n");

#ifndef _WIN32
  signal (SIGALRM, &starttls_alarm);
#endif

  /* do not buffer */
#if !(defined _WIN32 || defined __WIN32__)
  setbuf (stdin, NULL);
#endif
  setbuf (stdout, NULL);
  setbuf (stderr, NULL);

  for (;;)
    {
      if (starttls_alarmed && !hd.secure)
	{
	  fprintf (stderr, "*** Starting TLS handshake\n");
	  ret = do_handshake (&hd);
	  if (ret < 0)
	    {
	      fprintf (stderr, "*** Handshake has failed\n");
	      socket_bye (&hd);
	      user_term = 1;
	      break;
	    }
	}

      FD_ZERO (&rset);
      FD_SET (fileno (stdin), &rset);
      FD_SET (hd.fd, &rset);

      maxfd = MAX (fileno (stdin), hd.fd);
      tv.tv_sec = 3;
      tv.tv_usec = 0;

      err = select (maxfd + 1, &rset, NULL, NULL, &tv);
      if (err < 0)
	continue;

      if (FD_ISSET (hd.fd, &rset))
	{
	  memset (buffer, 0, MAX_BUF + 1);
	  ret = socket_recv (&hd, buffer, MAX_BUF);

	  if (ret == 0)
	    {
	      printf ("- Peer has closed the GNUTLS connection\n");
	      break;
	    }
	  else if (handle_error (&hd, ret) < 0 && user_term == 0)
	    {
	      fprintf (stderr,
		       "*** Server has terminated the connection abnormally.\n");
	      break;
	    }
	  else if (ret > 0)
	    {
	      if (verbose != 0)
		printf ("- Received[%d]: ", ret);
	      for (ii = 0; ii < ret; ii++)
		{
		  fputc (buffer[ii], stdout);
		}
	      fflush (stdout);
	    }

	  if (user_term != 0)
	    break;
	}

      if (FD_ISSET (fileno (stdin), &rset))
	{
	  if (fgets (buffer, MAX_BUF, stdin) == NULL)
	    {
	      if (hd.secure == 0)
		{
		  fprintf (stderr, "*** Starting TLS handshake\n");
		  ret = do_handshake (&hd);
		  if (ret < 0)
		    {
		      fprintf (stderr, "*** Handshake has failed\n");
		      socket_bye (&hd);
		      user_term = 1;
		    }
		}
	      else
		{
		  user_term = 1;
		  break;
		}
	      continue;
	    }

	  if (crlf != 0)
	    {
	      char *b = strchr (buffer, '\n');
	      if (b != NULL)
		strcpy (b, "\r\n");
	    }

	  ret = socket_send (&hd, buffer, strlen (buffer));

	  if (ret > 0)
	    {
	      if (verbose != 0)
		printf ("- Sent: %d bytes\n", ret);
	    }
	  else
	    handle_error (&hd, ret);

	}
    }

  if (user_term != 0)
    socket_bye (&hd);
  else
    gnutls_deinit (hd.session);

#ifdef ENABLE_SRP
  gnutls_srp_free_client_credentials (srp_cred);
#endif
#ifdef ENABLE_PSK
  gnutls_psk_free_client_credentials (psk_cred);
#endif

  gnutls_certificate_free_credentials (xcred);

#ifdef ENABLE_ANON
  gnutls_anon_free_client_credentials (anon_cred);
#endif

  gnutls_global_deinit ();

  return 0;
}
Esempio n. 9
0
int
connect_ssl(char *host, char *port,
	    int reconnect,
	    int use_sessionid, int use_ticket,
      int delay,
      const char *client_cert,
      const char *client_key) {
  struct addrinfo* addr;
  int err, s;
  char buffer[256];
  gnutls_anon_client_credentials_t anoncred;
  gnutls_certificate_credentials_t xcred;
  gnutls_session_t                 session;
  char                            *session_data = NULL;
  size_t                           session_data_size = 0;
  char                            *session_id = NULL;
  size_t                           session_id_size = 0;
  char                            *session_id_hex = NULL;
  char                            *session_id_p = NULL;
  unsigned                         session_id_idx;
  const char                      *hex = "0123456789ABCDEF";

  start("Initialize GNU TLS library");
  if ((err = gnutls_global_init()))
    fail("Unable to initialize GNU TLS:\n%s",
	 gnutls_strerror(err));
  if ((err = gnutls_anon_allocate_client_credentials(&anoncred)))
    fail("Unable to allocate anonymous client credentials:\n%s",
	 gnutls_strerror(err));
  if ((err = gnutls_certificate_allocate_credentials(&xcred)))
    fail("Unable to allocate X509 credentials:\n%s",
	 gnutls_strerror(err));

#ifdef DEBUG
  gnutls_global_set_log_function(debug);
  gnutls_global_set_log_level(10);
#endif

  addr = solve(host, port);
  do {
    start("Initialize TLS session");
    if ((err = gnutls_init(&session, GNUTLS_CLIENT)))
      fail("Unable to initialize the current session:\n%s",
	   gnutls_strerror(err));
    if ((err = gnutls_priority_set_direct(session, "PERFORMANCE:NORMAL:EXPORT", NULL)))
      fail("Unable to initialize cipher suites:\n%s",
	   gnutls_strerror(err));
    gnutls_dh_set_prime_bits(session, 512);
    if (client_cert == NULL) {
      if ((err = gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred)))
        fail("Unable to set anonymous credentials for session:\n%s",
	     gnutls_strerror(err));
    } else {
      if ((err = gnutls_certificate_set_x509_key_file(xcred, client_cert, client_key, GNUTLS_X509_FMT_PEM))) {
        fail("failed to load x509 certificate from file %s or key from %s: %s",client_cert,client_key,gnutls_strerror(err));
      }
    }
    if ((err = gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred)))
      fail("Unable to set credentials for session:\n%s",
	   gnutls_strerror(err));
    
    if (use_ticket) {
      start("Enable use of session tickets (RFC 5077)");
      if (gnutls_session_ticket_enable_client(session))
	fail("Unable to enable session tickets:\n%s",
	     gnutls_strerror(err));
    }

    if (session_data) {
      start("Copy old session");
      if ((err = gnutls_session_set_data(session, session_data, session_data_size)))
	fail("Unable to set session to previous one:\n%s",
	     gnutls_strerror(err));
    }

    s = connect_socket(addr, host, port);
    start("Start TLS renegotiation");
    gnutls_transport_set_ptr(session, (gnutls_transport_ptr_t)(uintptr_t)s);
    if ((err = gnutls_handshake(session))) {
      fail("Unable to start TLS renegotiation:\n%s",
	   gnutls_strerror(err));
    }

    start("Check if session was reused");
    if (!gnutls_session_is_resumed(session) && session_data)
      warn("No session was reused.");
    else if (gnutls_session_is_resumed(session) && !session_data)
      warn("Session was reused.");
    else if (gnutls_session_is_resumed(session))
      end("SSL session correctly reused");
    else
      end("SSL session was not used");

    start("Get current session");
    if (session_data) {
      free(session_data); session_data = NULL;
    }
    session_data_size = 8192;
    if ((err = gnutls_session_get_data(session, NULL, &session_data_size)))
      warn("No session available:\n%s",
          gnutls_strerror(err));
    else {
      session_data = malloc(session_data_size);
      if (!session_data) fail("No memory available");
      gnutls_session_get_data(session, session_data, &session_data_size);

      if ((err = gnutls_session_get_id( session, NULL, &session_id_size)))
         warn("No session id available:\n%s",
             gnutls_strerror(err));
      session_id = malloc(session_id_size);
      if (!session_id) fail("No memory available");
      else {
        if ((err = gnutls_session_get_id( session, session_id, &session_id_size)))
          warn("No session id available:\n%s",
            gnutls_strerror(err));
        session_id_hex = malloc(session_id_size * 2 + 1);
        if (!session_id_hex) fail("No memory available");
        else {
          for (session_id_p = session_id_hex, session_id_idx = 0;
               session_id_idx < session_id_size;
               ++session_id_idx) {
            *session_id_p++ = hex[ (session_id[session_id_idx] >> 4) & 0xf];
            *session_id_p++ = hex[ session_id[session_id_idx] & 0xf];
          }
          *session_id_p = '\0';

          end("Session context:\nProtocol : %s\nCipher : %s\nKx : %s\nCompression : %s\nPSK : %s\nID : %s",
            gnutls_protocol_get_name( gnutls_protocol_get_version(session) ),
            gnutls_cipher_get_name( gnutls_cipher_get(session) ),
            gnutls_kx_get_name( gnutls_kx_get(session) ),
            gnutls_compression_get_name( gnutls_compression_get(session)),
            gnutls_psk_server_get_username(session),
            session_id_hex
            );
          free(session_id_hex);
        }
        free(session_id);
      }
        
    }
    if (!use_sessionid && !use_ticket) {
      free(session_data); session_data = NULL;
    }

    start("Send HTTP GET");
    err = snprintf(buffer, sizeof(buffer),
		   "GET / HTTP/1.0\r\n"
		   "Host: %s\r\n"
		   "\r\n", host);
    if (err == -1 || err >= sizeof(buffer))
      fail("Unable to build request to send");
    if (gnutls_record_send(session, buffer, strlen(buffer)) < 0)
      fail("SSL write request failed:\n%s",
	   gnutls_strerror(err));

    start("Get HTTP answer");
    if ((err = gnutls_record_recv(session, buffer, sizeof(buffer) - 1)) <= 0)
      fail("SSL read request failed:\n%s",
	   gnutls_strerror(err));
    buffer[err] = '\0';
    if (strchr(buffer, '\r'))
      *strchr(buffer, '\r') = '\0';
    end("%s", buffer);

    start("End TLS connection");
    gnutls_bye(session, GNUTLS_SHUT_RDWR);
    close(s);
    gnutls_deinit (session);
    --reconnect;
    if (reconnect < 0) break;
    else {
      start("waiting %d seconds",delay);
      sleep(delay);
    }
  } while (1);

  if (session_data) free(session_data);
  gnutls_anon_free_client_credentials(anoncred);
  gnutls_global_deinit();
  return 0;
}
Esempio n. 10
0
int
print_info (gnutls_session_t session, const char *hostname, int insecure)
{
  const char *tmp;
  gnutls_credentials_type_t cred;
  gnutls_kx_algorithm_t kx;


  /* print the key exchange's algorithm name
   */
  kx = gnutls_kx_get (session);

  cred = gnutls_auth_get_type (session);
  switch (cred)
    {
#ifdef ENABLE_ANON
    case GNUTLS_CRD_ANON:
      print_dh_info (session, "Anonymous ");
      break;
#endif
#ifdef ENABLE_SRP
    case GNUTLS_CRD_SRP:
      /* This should be only called in server
       * side.
       */
      if (gnutls_srp_server_get_username (session) != NULL)
	printf ("- SRP authentication. Connected as '%s'\n",
		gnutls_srp_server_get_username (session));
      break;
#endif
#ifdef ENABLE_PSK
    case GNUTLS_CRD_PSK:
      /* This returns NULL in server side.
       */
      if (gnutls_psk_client_get_hint (session) != NULL)
	printf ("- PSK authentication. PSK hint '%s'\n",
		gnutls_psk_client_get_hint (session));
      /* This returns NULL in client side.
       */
      if (gnutls_psk_server_get_username (session) != NULL)
	printf ("- PSK authentication. Connected as '%s'\n",
		gnutls_psk_server_get_username (session));
      if (kx == GNUTLS_KX_DHE_PSK)
	print_dh_info (session, "Ephemeral ");
      break;
#endif
    case GNUTLS_CRD_IA:
      printf ("- TLS/IA authentication\n");
      break;
    case GNUTLS_CRD_CERTIFICATE:
      {
	char dns[256];
	size_t dns_size = sizeof (dns);
	unsigned int type;

	/* This fails in client side */
	if (gnutls_server_name_get (session, dns, &dns_size, &type, 0) == 0)
	  {
	    printf ("- Given server name[%d]: %s\n", type, dns);
	  }
      }

      if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS)
	print_dh_info (session, "Ephemeral ");

      print_cert_info (session, hostname, insecure);

      print_cert_vrfy (session);

    }

  tmp = SU (gnutls_protocol_get_name (gnutls_protocol_get_version (session)));
  printf ("- Version: %s\n", tmp);

  tmp = SU (gnutls_kx_get_name (kx));
  printf ("- Key Exchange: %s\n", tmp);

  tmp = SU (gnutls_cipher_get_name (gnutls_cipher_get (session)));
  printf ("- Cipher: %s\n", tmp);

  tmp = SU (gnutls_mac_get_name (gnutls_mac_get (session)));
  printf ("- MAC: %s\n", tmp);

  tmp = SU (gnutls_compression_get_name (gnutls_compression_get (session)));
  printf ("- Compression: %s\n", tmp);

  if (verbose)
    {
      char id[32];
      size_t id_size = sizeof (id);
      gnutls_session_get_id (session, id, &id_size);
      printf ("- Session ID: %s\n", raw_to_string (id, id_size));
    }


  fflush (stdout);

  return 0;
}
void session::get_id (void *session_id, size_t * session_id_size) const
{
    RETWRAP (gnutls_session_get_id (s, session_id, session_id_size));
}