Exemple #1
0
/**
 * gnutls_session_get_data:
 * @session: is a #gnutls_session_t type.
 * @session_data: is a pointer to space to hold the session.
 * @session_data_size: is the session_data's size, or it will be set by the function.
 *
 * Returns all session parameters needed to be stored to support resumption.
 * The client should call this, and store the returned session data. A session
 * may be resumed later by calling gnutls_session_set_data().  
 *
 * This function will fail if called prior to handshake completion. In
 * case of false start TLS, the handshake completes only after data have
 * been successfully received from the peer.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
 *   an error code is returned.
 **/
int
gnutls_session_get_data(gnutls_session_t session,
			void *session_data, size_t * session_data_size)
{

	gnutls_datum_t psession;
	int ret;

	ret = gnutls_session_get_data2(session, &psession);
	if (ret < 0) {
		gnutls_assert();
		return ret;
	}

	if (psession.size > *session_data_size) {
		*session_data_size = psession.size;
		ret = GNUTLS_E_SHORT_MEMORY_BUFFER;
		goto error;
	}
	*session_data_size = psession.size;

	if (session_data != NULL)
		memcpy(session_data, psession.data, psession.size);

	ret = 0;

      error:
	_gnutls_free_datum(&psession);
	return ret;
}
static int ticket_callback(gnutls_session_t session, unsigned int htype,
			   unsigned post, unsigned int incoming, const gnutls_datum_t *msg)
{
	gnutls_datum *d;
	static int counter = 0;
	int ret;

	assert(htype == GNUTLS_HANDSHAKE_NEW_SESSION_TICKET);

	counter++;
	if (counter <= TLS13_TICKETS_TO_SEND) /* ignore the default tickets sent */
		return 0;

	d = gnutls_session_get_ptr(session);

	if (post == GNUTLS_HOOK_POST) {
		tickets_seen++;
		if (d->data)
			gnutls_free(d->data);
		ret = gnutls_session_get_data2(session, d);
		assert(ret >= 0);
		assert(d->size > 4);

		return 0;
	}

	return 0;
}
static void
g_tls_client_connection_gnutls_finish_handshake (GTlsConnectionGnutls  *conn,
						 GError               **inout_error)
{
  GTlsClientConnectionGnutls *gnutls = G_TLS_CLIENT_CONNECTION_GNUTLS (conn);
  int resumed;

  g_assert (inout_error != NULL);

  if (g_error_matches (*inout_error, G_TLS_ERROR, G_TLS_ERROR_NOT_TLS) &&
      gnutls->priv->cert_requested)
    {
      g_clear_error (inout_error);
      if (gnutls->priv->cert_error)
	{
	  *inout_error = gnutls->priv->cert_error;
	  gnutls->priv->cert_error = NULL;
	}
      else
	{
	  g_set_error_literal (inout_error, G_TLS_ERROR, G_TLS_ERROR_CERTIFICATE_REQUIRED,
			       _("Server required TLS certificate"));
	}
    }

  resumed = gnutls_session_is_resumed (g_tls_connection_gnutls_get_session (conn));
  if (*inout_error || !resumed)
    {
      /* Clear session data since the server did not accept what we provided. */
      gnutls->priv->session_data_override = FALSE;
      g_clear_pointer (&gnutls->priv->session_data, g_bytes_unref);
      if (gnutls->priv->session_id)
        g_tls_backend_gnutls_remove_session (GNUTLS_CLIENT, gnutls->priv->session_id);
    }

  if (!*inout_error && !resumed)
    {
      gnutls_datum_t session_datum;

      if (gnutls_session_get_data2 (g_tls_connection_gnutls_get_session (conn),
                                    &session_datum) == 0)
        {
          gnutls->priv->session_data = g_bytes_new_with_free_func (session_datum.data,
                                                                   session_datum.size,
                                                                   (GDestroyNotify)gnutls_free,
                                                                   session_datum.data);

          g_tls_backend_gnutls_store_session (GNUTLS_CLIENT,
                                              gnutls->priv->session_id,
                                              gnutls->priv->session_data);
        }
    }
}
Exemple #4
0
bool CTlsSocket::CopySessionData(const CTlsSocket* pPrimarySocket)
{
	gnutls_datum_t d;
	int res = gnutls_session_get_data2(pPrimarySocket->m_session, &d);
	if (res) {
		m_pOwner->LogMessage(MessageType::Debug_Warning, _T("gnutls_session_get_data2 on primary socket failed: %d"), res);
		return true;
	}

	// Set session data
	res = gnutls_session_set_data(m_session, d.data, d.size );
	gnutls_free(d.data);
	if (res) {
		m_pOwner->LogMessage(MessageType::Debug_Info, _T("gnutls_session_set_data failed: %d. Going to reinitialize session."), res);
		UninitSession();
		if (!InitSession())
			return false;
	}
	else
		m_pOwner->LogMessage(MessageType::Debug_Info, _T("Trying to resume existing TLS session."));

	return true;
}
Exemple #5
0
static void client(int sds[], struct params_res *params)
{
	int ret, ii;
	gnutls_session_t session;
	char buffer[MAX_BUF + 1];
	gnutls_anon_client_credentials_t anoncred;
	/* Need to enable anonymous KX specifically. */

	/* variables used in session resuming
	 */
	int t;
	gnutls_datum_t session_data;

	if (debug) {
		gnutls_global_set_log_function(tls_log_func);
		gnutls_global_set_log_level(3);
	}
	global_init();

	gnutls_anon_allocate_client_credentials(&anoncred);

	for (t = 0; t < SESSIONS; t++) {
		int sd = sds[t];

		/* Initialize TLS session
		 */
		gnutls_init(&session,
			    GNUTLS_CLIENT | GNUTLS_DATAGRAM);

		/* Use default priorities */
		if (params->enable_session_ticket_client)
			gnutls_priority_set_direct(session,
					   "NONE:+VERS-DTLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-DH",
					   NULL);
		else
			gnutls_priority_set_direct(session,
					   "NONE:+VERS-DTLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-DH:%NO_TICKETS",
					   NULL);

		/* put the anonymous credentials to the current session
		 */
		gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred);

		if (t > 0) {
			/* if this is not the first time we connect */
			gnutls_session_set_data(session, session_data.data,
						session_data.size);
			gnutls_free(session_data.data);
		}

		gnutls_transport_set_int(session, sd);

		/* Perform the TLS handshake
		 */
		gnutls_dtls_set_timeouts(session, 3*1000, 240 * 1000);
		do {
			ret = gnutls_handshake(session);
		} while (ret < 0 && gnutls_error_is_fatal(ret) == 0);

		if (ret < 0) {
			gnutls_perror(ret);
			fail("client: Handshake failed\n");
			goto end;
		} else {
			if (debug)
				success
				    ("client: Handshake was completed\n");
		}

		if (t == 0) {	/* the first time we connect */
			/* get the session data size */
			ret =
			    gnutls_session_get_data2(session,
						     &session_data);
			if (ret < 0)
				fail("Getting resume data failed\n");
		} else {	/* the second time we connect */

			/* check if we actually resumed the previous session */
			if (gnutls_session_is_resumed(session) != 0) {
				if (params->expect_resume) {
					if (debug)
						success
						    ("- Previous session was resumed\n");
				} else
					fail("- Previous session was resumed\n");
			} else {
				if (params->expect_resume) {
					fail("*** Previous session was NOT resumed\n");
				} else {
					if (debug)
						success
						    ("*** Previous session was NOT resumed (expected)\n");
				}
			}
		}

		gnutls_record_send(session, MSG, strlen(MSG));

		ret = gnutls_record_recv(session, buffer, MAX_BUF);
		if (ret == 0) {
			if (debug)
				success
				    ("client: Peer has closed the TLS connection\n");
			goto end;
		} else if (ret < 0) {
			fail("client: Error: %s\n", gnutls_strerror(ret));
			goto end;
		}

		if (debug) {
			printf("- Received %d bytes: ", ret);
			for (ii = 0; ii < ret; ii++) {
				fputc(buffer[ii], stdout);
			}
			fputs("\n", stdout);
		}

		gnutls_bye(session, GNUTLS_SHUT_RDWR);

		close(sd);

		gnutls_deinit(session);
	}

      end:
	gnutls_anon_free_client_credentials(anoncred);
}
Exemple #6
0
/* Returns true if resumed */
static unsigned handshake(const char *prio, unsigned t, const gnutls_datum_t *sdata,
			  gnutls_datum_t *ndata,
			  gnutls_datum_t *skey,
			  struct hsk_st *h)
{
	int ret;
	/* Server stuff. */
	gnutls_certificate_credentials_t serverx509cred;
	gnutls_session_t server;
	int sret = GNUTLS_E_AGAIN;
	/* Client stuff. */
	gnutls_certificate_credentials_t clientx509cred;
	gnutls_session_t client;
	int cret = GNUTLS_E_AGAIN;
	char buf[128];

	gnutls_global_set_log_function(tls_log_func);
	if (debug)
		gnutls_global_set_log_level(6);

	assert(gnutls_certificate_allocate_credentials(&serverx509cred)>=0);
	assert(gnutls_certificate_set_x509_key_mem(serverx509cred,
					    &server_cert, &server_key,
					    GNUTLS_X509_FMT_PEM)>=0);

	assert(gnutls_init(&server, GNUTLS_SERVER)>=0);
	gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE,
				serverx509cred);
	assert(gnutls_priority_set_direct(server, prio, NULL)>=0);
	gnutls_transport_set_push_function(server, server_push);
	gnutls_transport_set_pull_function(server, server_pull);
	gnutls_transport_set_ptr(server, server);
	gnutls_session_set_ptr(server, h);

	gnutls_db_set_cache_expiration(server, t);
	assert(gnutls_session_ticket_enable_server(server, skey) >= 0);

	gnutls_handshake_set_hook_function(server, -1,
					   GNUTLS_HOOK_POST,
					   handshake_callback);

	assert(gnutls_certificate_allocate_credentials(&clientx509cred)>=0);
	assert(gnutls_certificate_set_x509_trust_mem(clientx509cred, &ca_cert, GNUTLS_X509_FMT_PEM)>=0);
	assert(gnutls_init(&client, GNUTLS_CLIENT)>=0);

	assert(gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE,
				      clientx509cred)>=0);

	assert(gnutls_priority_set_direct(client, prio, NULL)>=0);
	gnutls_transport_set_push_function(client, client_push);
	gnutls_transport_set_pull_function(client, client_pull);
	gnutls_transport_set_ptr(client, client);

	if (sdata) {
		assert(gnutls_session_set_data(client, sdata->data, sdata->size)>=0);
	}

	memset(buf, 0, sizeof(buf));
	ret = gnutls_session_set_data(client, buf, sizeof(buf));
	if (ret != GNUTLS_E_DB_ERROR) {
		fail("unexpected error: %s\n", gnutls_strerror(ret));
	}

	HANDSHAKE(client, server);

	gnutls_record_recv(client, buf, sizeof(buf));

	if (ndata) {
		ret = gnutls_session_get_data2(client, ndata);
		if (ret < 0) {
			fail("unexpected error: %s\n", gnutls_strerror(ret));
		}
	}

	ret = gnutls_session_is_resumed(client);

	gnutls_deinit(server);
	gnutls_deinit(client);

	gnutls_certificate_free_credentials(serverx509cred);
	gnutls_certificate_free_credentials(clientx509cred);

	reset_buffers();
	return ret;
}
Exemple #7
0
void
client (void)
{
  int ret, sd, ii;
  gnutls_session_t session;
  char buffer[MAX_BUF + 1];
  gnutls_anon_client_credentials_t anoncred;
  /* Need to enable anonymous KX specifically. */
  const int kx_prio[] = { GNUTLS_KX_ANON_DH, 0 };

  /* variables used in session resuming
   */
  int t;
  gnutls_datum session_data;

  gnutls_global_init ();

  gnutls_anon_allocate_client_credentials (&anoncred);

  for (t = 0; t < 2; t++)
    {				/* connect 2 times to the server */

      /* connect to the peer
       */
      sd = tcp_connect ();

      /* Initialize TLS session
       */
      gnutls_init (&session, GNUTLS_CLIENT);

      /* Use default priorities */
      gnutls_set_default_priority (session);
      gnutls_kx_set_priority (session, kx_prio);

      /* put the anonymous credentials to the current session
       */
      gnutls_credentials_set (session, GNUTLS_CRD_ANON, anoncred);

      if (t > 0)
	{
	  /* if this is not the first time we connect */
	  gnutls_session_set_data (session, session_data.data,
				   session_data.size);
	  gnutls_free (session_data.data);
	}

      gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) sd);

      /* Perform the TLS handshake
       */
      ret = gnutls_handshake (session);

      if (ret < 0)
	{
	  fail ("client: Handshake failed\n");
	  gnutls_perror (ret);
	  goto end;
	}
      else
	{
	  success ("client: Handshake was completed\n");
	}

      if (t == 0)
	{			/* the first time we connect */
	  /* get the session data size */
	  ret = gnutls_session_get_data2 (session, &session_data);
	  if (ret < 0)
	    fail ("Getting resume data failed\n");
	}
      else
	{			/* the second time we connect */

	  /* check if we actually resumed the previous session */
	  if (gnutls_session_is_resumed (session) != 0)
	    {
	      success ("- Previous session was resumed\n");
	    }
	  else
	    {
	      success ("*** Previous session was NOT resumed\n");
	    }
	}

      gnutls_record_send (session, MSG, strlen (MSG));

      ret = gnutls_record_recv (session, buffer, MAX_BUF);
      if (ret == 0)
	{
	  success ("client: Peer has closed the TLS connection\n");
	  goto end;
	}
      else if (ret < 0)
	{
	  fail ("client: Error: %s\n", gnutls_strerror (ret));
	  goto end;
	}

      if (debug)
	{
	  printf ("- Received %d bytes: ", ret);
	  for (ii = 0; ii < ret; ii++)
	    {
	      fputc (buffer[ii], stdout);
	    }
	  fputs ("\n", stdout);
	}

      gnutls_bye (session, GNUTLS_SHUT_RDWR);

    end:

      tcp_close (sd);

      gnutls_deinit (session);
    }

  gnutls_anon_free_client_credentials (anoncred);
}
Exemple #8
0
int ne_sock_connect_ssl(ne_socket *sock, ne_ssl_context *ctx, void *userdata)
{
    int ret;

#if defined(HAVE_OPENSSL)
    SSL *ssl;

    if (seed_ssl_prng()) {
	set_error(sock, _("SSL disabled due to lack of entropy"));
	return NE_SOCK_ERROR;
    }

    /* If runtime library version differs from compile-time version
     * number in major/minor/fix level, abort soon. */
    if ((SSLeay() ^ OPENSSL_VERSION_NUMBER) & 0xFFFFF000) {
        set_error(sock, _("SSL disabled due to library version mismatch"));
        return NE_SOCK_ERROR;
    }

    sock->ssl = ssl = SSL_new(ctx->ctx);
    if (!ssl) {
	set_error(sock, _("Could not create SSL structure"));
	return NE_SOCK_ERROR;
    }
    
    SSL_set_app_data(ssl, userdata);
    SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
    SSL_set_fd(ssl, sock->fd);
    sock->ops = &iofns_ssl;
    
    if (ctx->sess)
	SSL_set_session(ssl, ctx->sess);

    ret = SSL_connect(ssl);
    if (ret != 1) {
	error_ossl(sock, ret);
	SSL_free(ssl);
	sock->ssl = NULL;
	return NE_SOCK_ERROR;
    }
#elif defined(HAVE_GNUTLS)
    /* DH and RSA params are set in ne_ssl_context_create */
    gnutls_init(&sock->ssl, GNUTLS_CLIENT);
    gnutls_set_default_priority(sock->ssl);
    gnutls_session_set_ptr(sock->ssl, userdata);
    gnutls_credentials_set(sock->ssl, GNUTLS_CRD_CERTIFICATE, ctx->cred);

    gnutls_transport_set_ptr(sock->ssl, (gnutls_transport_ptr) sock->fd);

    if (ctx->cache.client.data) {
#if defined(HAVE_GNUTLS_SESSION_GET_DATA2)
        gnutls_session_set_data(sock->ssl, 
                                ctx->cache.client.data, 
                                ctx->cache.client.size);
#else
        gnutls_session_set_data(sock->ssl, 
                                ctx->cache.client.data, 
                                ctx->cache.client.len);
#endif
    }
    sock->ops = &iofns_ssl;

    ret = gnutls_handshake(sock->ssl);
    if (ret < 0) {
	error_gnutls(sock, ret);
        return NE_SOCK_ERROR;
    }

    if (!gnutls_session_is_resumed(sock->ssl)) {
        /* New session.  The old method of using the _get_data
         * function seems to be broken with 1.3.0 and later*/
#if defined(HAVE_GNUTLS_SESSION_GET_DATA2)
        gnutls_session_get_data2(sock->ssl, &ctx->cache.client);
#else
        ctx->cache.client.len = 0;
        if (gnutls_session_get_data(sock->ssl, NULL, 
                                    &ctx->cache.client.len) == 0) {
            ctx->cache.client.data = ne_malloc(ctx->cache.client.len);
            gnutls_session_get_data(sock->ssl, ctx->cache.client.data, 
                                    &ctx->cache.client.len);
        }
#endif
    }
#endif
    return 0;
}
void doit(void)
{
	int exit_code = EXIT_SUCCESS;
	int ret;
	/* Server stuff. */
	gnutls_certificate_credentials_t serverx509cred;
	gnutls_session_t server;
	int sret = GNUTLS_E_AGAIN;
	/* Client stuff. */
	gnutls_certificate_credentials_t clientx509cred;
	gnutls_session_t client;
	int cret = GNUTLS_E_AGAIN;
	gnutls_datum_t data;
	char buf[128];

	/* General init. */
	global_init();
	gnutls_global_set_log_function(tls_log_func);
	if (debug)
		gnutls_global_set_log_level(6);

	gnutls_global_set_time_function(mytime);

	/* Init server */
	gnutls_certificate_allocate_credentials(&serverx509cred);
	gnutls_certificate_set_x509_key_mem(serverx509cred,
					    &server_cert, &server_key,
					    GNUTLS_X509_FMT_PEM);

	gnutls_init(&server, GNUTLS_SERVER);
	gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE,
				serverx509cred);
	gnutls_set_default_priority(server);
	gnutls_transport_set_push_function(server, server_push);
	gnutls_transport_set_pull_function(server, server_pull);
	gnutls_transport_set_ptr(server, server);

	/* Init client */
	ret = gnutls_certificate_allocate_credentials(&clientx509cred);
	if (ret < 0)
		exit(1);

	ret = gnutls_certificate_set_x509_trust_mem(clientx509cred, &ca_cert, GNUTLS_X509_FMT_PEM);
	if (ret < 0)
		exit(1);

	ret = gnutls_init(&client, GNUTLS_CLIENT|GNUTLS_ENABLE_FALSE_START);
	if (ret < 0)
		exit(1);

	ret = gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE,
				clientx509cred);
	if (ret < 0)
		exit(1);

	gnutls_set_default_priority(client);
	gnutls_transport_set_push_function(client, client_push);
	gnutls_transport_set_pull_function(client, client_pull);
	gnutls_transport_set_ptr(client, client);

	memset(buf, 0, sizeof(buf));
	ret = gnutls_session_set_data(client, buf, sizeof(buf));
	if (ret != GNUTLS_E_DB_ERROR) {
		fail("unexpected error: %s\n", gnutls_strerror(ret));
	}

	HANDSHAKE(client, server);

	/* try obtaining the resumption data. This should fail because
	 * the handshake is not yet complete (due to false start) */
	ret = gnutls_session_get_data2(client, &data);
	if (ret != GNUTLS_E_UNAVAILABLE_DURING_HANDSHAKE) {
		fail("unexpected error: %s\n", gnutls_strerror(ret));
	}

	ret = gnutls_record_recv(client, buf, sizeof(buf));
	if (ret < 0 && ret != GNUTLS_E_AGAIN) {
		fail("unexpected error: %s\n", gnutls_strerror(ret));
	}

	ret = gnutls_session_get_data2(client, &data);
	if (ret != 0) {
		fail("unexpected error: %s\n", gnutls_strerror(ret));
	}
	gnutls_free(data.data);

	gnutls_bye(client, GNUTLS_SHUT_RDWR);
	gnutls_bye(server, GNUTLS_SHUT_RDWR);

	gnutls_deinit(client);
	gnutls_deinit(server);

	gnutls_certificate_free_credentials(serverx509cred);
	gnutls_certificate_free_credentials(clientx509cred);

	gnutls_global_deinit();

	if (debug > 0) {
		if (exit_code == 0)
			puts("Self-test successful");
		else
			puts("Self-test failed");
	}
}
void session::get_data (gnutls_session_t session, gnutls_datum_t & data) const
{
    RETWRAP (gnutls_session_get_data2 (s, &data));

}