コード例 #1
0
ファイル: finished.c プロジェクト: ystk/debian-gnutls26
void
doit (void)
{
  /* Server stuff. */
  gnutls_anon_server_credentials_t s_anoncred;
  const gnutls_datum_t p3 = { (char*) pkcs3, strlen (pkcs3) };
  static gnutls_dh_params_t dh_params;
  gnutls_session_t server;
  int sret = GNUTLS_E_AGAIN;
  /* Client stuff. */
  gnutls_anon_client_credentials_t c_anoncred;
  gnutls_session_t client;
  int n, cret = GNUTLS_E_AGAIN;
  /* Need to enable anonymous KX specifically. */
  const int kx_prio[] = { GNUTLS_KX_ANON_DH, 0 };
  char buffer[MAX_BUF + 1];
  ssize_t ns;
  int ret;

  /* General init. */
  gnutls_global_init ();
  gnutls_global_set_log_function (tls_log_func);
  if (debug)
    gnutls_global_set_log_level (4711);

  /* Init server */
  gnutls_anon_allocate_server_credentials (&s_anoncred);
  gnutls_dh_params_init (&dh_params);
  gnutls_dh_params_import_pkcs3 (dh_params, &p3, GNUTLS_X509_FMT_PEM);
  gnutls_anon_set_server_dh_params (s_anoncred, dh_params);
  gnutls_init (&server, GNUTLS_SERVER);
  gnutls_set_default_priority (server);
  gnutls_kx_set_priority (server, kx_prio);
  gnutls_credentials_set (server, GNUTLS_CRD_ANON, s_anoncred);
  gnutls_dh_set_prime_bits (server, 1024);
  gnutls_transport_set_push_function (server, server_push);
  gnutls_transport_set_pull_function (server, server_pull);
  gnutls_session_set_finished_function (server, server_finished_callback);

  /* Init client */
  gnutls_anon_allocate_client_credentials (&c_anoncred);
  gnutls_init (&client, GNUTLS_CLIENT);
  gnutls_set_default_priority (client);
  gnutls_kx_set_priority (client, kx_prio);
  gnutls_credentials_set (client, GNUTLS_CRD_ANON, c_anoncred);
  gnutls_transport_set_push_function (client, client_push);
  gnutls_transport_set_pull_function (client, client_pull);
  gnutls_session_set_finished_function (client, client_finished_callback);

  do
    {
      if (cret == GNUTLS_E_AGAIN)
	{
	  success ("loop invoking client:\n");
	  cret = gnutls_handshake (client);
	  success ("client %d: %s\n", cret, gnutls_strerror (cret));
	}

      if (sret == GNUTLS_E_AGAIN)
	{
	  success ("loop invoking server:\n");
	  sret = gnutls_handshake (server);
	  success ("server %d: %s\n", sret, gnutls_strerror (sret));
	}
    }
  while (cret == GNUTLS_E_AGAIN || sret == GNUTLS_E_AGAIN);

  success ("Handshake established\n");

  ns = gnutls_record_send (client, MSG, strlen (MSG));
  success ("client: sent %d\n", ns);

  ret = gnutls_record_recv (server, buffer, MAX_BUF);
  if (ret == 0)
    fail ("server: didn't receive any data\n");
  else if (ret < 0)
    fail ("server: error: %s\n", gnutls_strerror (ret));
  else
    {
      printf ("server: received %d: ", ret);
      for (n = 0; n < ret; n++)
	fputc (buffer[n], stdout);
      fputs ("\n", stdout);
    }

  ns = gnutls_record_send (server, MSG, strlen (MSG));
  success ("server: sent %d\n", ns);

  ret = gnutls_record_recv (client, buffer, MAX_BUF);
  if (ret == 0)
    {
      fail ("client: Peer has closed the TLS connection\n");
    }
  else if (ret < 0)
    {
      fail ("client: Error: %s\n", gnutls_strerror (ret));
    }
  else
    {
      printf ("client: received %d: ", ret);
      for (n = 0; n < ret; n++)
	fputc (buffer[n], stdout);
      fputs ("\n", stdout);
    }

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

  gnutls_deinit (client);
  gnutls_deinit (server);

  free (to_server);
  free (to_client);

  gnutls_anon_free_client_credentials (c_anoncred);
  gnutls_anon_free_server_credentials (s_anoncred);

  gnutls_dh_params_deinit (dh_params);

  gnutls_global_deinit ();
}
コード例 #2
0
ファイル: record-sizes.c プロジェクト: Distrotech/gnutls
void doit(void)
{
	/* Server stuff. */
	gnutls_anon_server_credentials_t s_anoncred;
	const gnutls_datum_t p3 =
	    { (unsigned char *) pkcs3, strlen(pkcs3) };
	static gnutls_dh_params_t dh_params;
	gnutls_session_t server;
	int sret = GNUTLS_E_AGAIN;
	/* Client stuff. */
	gnutls_anon_client_credentials_t c_anoncred;
	gnutls_session_t client;
	int cret = GNUTLS_E_AGAIN, i;
	/* Need to enable anonymous KX specifically. */
	ssize_t ns;
	int ret, transferred = 0;

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

	/* Init server */
	gnutls_anon_allocate_server_credentials(&s_anoncred);
	gnutls_dh_params_init(&dh_params);
	gnutls_dh_params_import_pkcs3(dh_params, &p3, GNUTLS_X509_FMT_PEM);
	gnutls_anon_set_server_dh_params(s_anoncred, dh_params);
	gnutls_init(&server, GNUTLS_SERVER);
	gnutls_priority_set_direct(server,
				   "NONE:+VERS-TLS-ALL:+ARCFOUR-128:+MAC-ALL:+SIGN-ALL:+COMP-NULL:+ANON-DH",
				   NULL);
	gnutls_credentials_set(server, GNUTLS_CRD_ANON, s_anoncred);
	gnutls_transport_set_push_function(server, server_push);
	gnutls_transport_set_pull_function(server, server_pull);
	gnutls_transport_set_ptr(server, server);

	/* Init client */
	gnutls_anon_allocate_client_credentials(&c_anoncred);
	gnutls_init(&client, GNUTLS_CLIENT);
	gnutls_priority_set_direct(client,
				   "NONE:+VERS-TLS-ALL:+CIPHER-ALL:+ARCFOUR-128:+MAC-ALL:+SIGN-ALL:+COMP-NULL:+ANON-DH",
				   NULL);
	gnutls_credentials_set(client, GNUTLS_CRD_ANON, c_anoncred);
	gnutls_transport_set_push_function(client, client_push);
	gnutls_transport_set_pull_function(client, client_pull);
	gnutls_transport_set_ptr(client, client);

	memset(b1, 0, sizeof(b1));
	HANDSHAKE(client, server);

	if (debug)
		success("Handshake established\n");

	memset(b1, 1, MAX_BUF);

	/* try the maximum allowed */
	ret = gnutls_record_send(client, b1, MAX_BUF);
	if (ret < 0) {
		fprintf(stderr, "Error sending %d bytes: %s\n",
			(int) MAX_BUF, gnutls_strerror(ret));
		exit(1);
	}

	if (ret != MAX_BUF) {
		fprintf(stderr, "Couldn't send %d bytes\n", (int) MAX_BUF);
		exit(1);
	}

	ret = gnutls_record_recv(server, buffer, MAX_BUF);
	if (ret < 0) {
		fprintf(stderr, "Error receiving %d bytes: %s\n",
			(int) MAX_BUF, gnutls_strerror(ret));
		exit(1);
	}

	if (ret != MAX_BUF) {
		fprintf(stderr, "Couldn't receive %d bytes, received %d\n",
			(int) MAX_BUF, ret);
		exit(1);
	}

	if (memcmp(b1, buffer, MAX_BUF) != 0) {
		fprintf(stderr, "Buffers do not match!\n");
		exit(1);
	}

	/* Try sending various other sizes */
	for (i = 1; i < 128; i++) {
		TRANSFER(client, server, b1, i, buffer, MAX_BUF);
	}
	if (debug)
		fputs("\n", stdout);



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

	gnutls_deinit(client);
	gnutls_deinit(server);

	gnutls_anon_free_client_credentials(c_anoncred);
	gnutls_anon_free_server_credentials(s_anoncred);

	gnutls_dh_params_deinit(dh_params);

	gnutls_global_deinit();
}
コード例 #3
0
static void
server (int fd, const char* prio)
{
int ret;
char buffer[MAX_BUF + 1];
gnutls_session_t session;
gnutls_anon_server_credentials_t anoncred;
gnutls_certificate_credentials_t x509_cred;
gnutls_range_st range;

  to_send = 0;

  range.low = MAX_BUF;
  range.high = HIGH(MAX_BUF);

  /* this must be called once in the program
   */
  global_init ();
  memset(buffer, 0, sizeof(buffer));

  if (debug)
    {
      gnutls_global_set_log_function (server_log_func);
      gnutls_global_set_log_level (4711);
    }

  gnutls_certificate_allocate_credentials (&x509_cred);
  gnutls_certificate_set_x509_key_mem (x509_cred, &server_cert, &server_key,
                                       GNUTLS_X509_FMT_PEM);

  gnutls_anon_allocate_server_credentials (&anoncred);

  gnutls_init (&session, GNUTLS_SERVER);

  /* avoid calling all the priority functions, since the defaults
   * are adequate.
   */
  gnutls_priority_set_direct (session, prio, NULL);

  gnutls_credentials_set (session, GNUTLS_CRD_ANON, anoncred);
  gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, x509_cred);

  gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) fd);

  do 
    {
      ret = gnutls_handshake (session);
    }
  while (ret < 0 && gnutls_error_is_fatal(ret) == 0);
  if (ret < 0)
    {
      close (fd);
      gnutls_deinit (session);
      fail ("server: Handshake has failed (%s)\n\n", gnutls_strerror (ret));
      terminate();
    }
  if (debug)
    success ("server: Handshake was completed\n");

  if (debug)
    success ("server: TLS version is: %s\n",
             gnutls_protocol_get_name (gnutls_protocol_get_version
                                       (session)));

  gnutls_transport_set_push_function (session, push);
  
  if (gnutls_record_can_use_length_hiding(session) == 0)
    {
      fail("Length hiding isn't possible\n");
      terminate();
    }
  
  do
    {
      do {
        ret = gnutls_record_send_range (session, buffer, sizeof (buffer), &range);
      } while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED);

      if (ret < 0)
        {
          fail("Error sending packet: %s\n", gnutls_strerror(ret));
          terminate();
        }
      to_send++;
    }
  while(to_send < 4);

  to_send = -1;
  /* do not wait for the peer to close the connection.
   */
  gnutls_bye (session, GNUTLS_SHUT_WR);

  close (fd);
  gnutls_deinit (session);

  gnutls_anon_free_server_credentials (anoncred);
  gnutls_certificate_free_credentials (x509_cred);

  gnutls_global_deinit ();

  if (debug)
    success ("server: finished\n");
}
コード例 #4
0
void dtls_try_with_key_mtu(const char *name, const char *client_prio, gnutls_kx_algorithm_t client_kx,
		gnutls_sign_algorithm_t server_sign_algo,
		gnutls_sign_algorithm_t client_sign_algo,
		const gnutls_datum_t *serv_cert,
		const gnutls_datum_t *serv_key,
		const gnutls_datum_t *client_cert,
		const gnutls_datum_t *client_key,
		unsigned cert_flags,
		unsigned smtu)
{
	int ret;
	char buffer[256];
	/* Server stuff. */
	gnutls_certificate_credentials_t serverx509cred;
	gnutls_anon_server_credentials_t s_anoncred;
	gnutls_dh_params_t dh_params;
	const gnutls_datum_t p3 =
	    { (unsigned char *) pkcs3, strlen(pkcs3) };
	gnutls_session_t server;
	int sret = GNUTLS_E_AGAIN;
	/* Client stuff. */
	gnutls_certificate_credentials_t clientx509cred;
	gnutls_anon_client_credentials_t c_anoncred;
	gnutls_session_t client;
	int cret = GNUTLS_E_AGAIN, version;

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

	reset_buffers();
	/* Init server */
	gnutls_anon_allocate_server_credentials(&s_anoncred);
	gnutls_certificate_allocate_credentials(&serverx509cred);

	ret = gnutls_certificate_set_x509_key_mem(serverx509cred,
					    serv_cert, serv_key,
					    GNUTLS_X509_FMT_PEM);
	if (ret < 0) {
		fail("Could not set key/cert: %s\n", gnutls_strerror(ret));
	}

	gnutls_dh_params_init(&dh_params);
	gnutls_dh_params_import_pkcs3(dh_params, &p3, GNUTLS_X509_FMT_PEM);
	gnutls_certificate_set_dh_params(serverx509cred, dh_params);
	gnutls_anon_set_server_dh_params(s_anoncred, dh_params);

	assert(gnutls_init(&server, GNUTLS_SERVER|GNUTLS_DATAGRAM|GNUTLS_NONBLOCK)>=0);
	assert(gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE,
				      serverx509cred)>=0);
	assert(gnutls_credentials_set(server, GNUTLS_CRD_ANON, s_anoncred)>=0);

	assert(gnutls_priority_set_direct(server,
					  "NORMAL:+ANON-ECDH:+ANON-DH:+ECDHE-RSA:+DHE-RSA:+RSA:+ECDHE-ECDSA:+CURVE-X25519",
					   NULL)>=0);
	gnutls_transport_set_push_function(server, server_push);
	gnutls_transport_set_pull_function(server, server_pull);
	gnutls_transport_set_pull_timeout_function(server, server_pull_timeout_func);
	gnutls_transport_set_ptr(server, server);
	if (smtu)
		gnutls_dtls_set_mtu (server, smtu);

	/* Init client */

	ret = gnutls_certificate_allocate_credentials(&clientx509cred);
	if (ret < 0)
		exit(1);

	if (cert_flags == USE_CERT) {
		ret = gnutls_certificate_set_x509_key_mem(clientx509cred,
						    client_cert, client_key,
						    GNUTLS_X509_FMT_PEM);
		if (ret < 0) {
			fail("Could not set key/cert: %s\n", gnutls_strerror(ret));
		}
		gnutls_certificate_server_set_request(server, GNUTLS_CERT_REQUIRE);
	} else if (cert_flags == ASK_CERT) {
		gnutls_certificate_server_set_request(server, GNUTLS_CERT_REQUEST);
	}

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

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

	assert(gnutls_anon_allocate_client_credentials(&c_anoncred)>=0);
	assert(gnutls_credentials_set(client, GNUTLS_CRD_ANON, c_anoncred)>=0);
	ret = gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE,
				clientx509cred);
	if (ret < 0)
		exit(1);

	gnutls_transport_set_push_function(client, client_push);
	gnutls_transport_set_pull_function(client, client_pull);
	gnutls_transport_set_pull_timeout_function(client, client_pull_timeout_func);

	gnutls_transport_set_ptr(client, client);
	if (smtu)
		gnutls_dtls_set_mtu (client, smtu);

	ret = gnutls_priority_set_direct(client, client_prio, NULL);
	if (ret < 0) {
		exit(1);
	}
	success("negotiating %s\n", name);
	HANDSHAKE_DTLS(client, server);

	if (gnutls_kx_get(client) != client_kx) {
		fail("%s: got unexpected key exchange algorithm: %s (expected %s)\n", name, gnutls_kx_get_name(gnutls_kx_get(client)),
			gnutls_kx_get_name(client_kx));
		exit(1);
	}


	/* test signature algorithm match */
	version = gnutls_protocol_get_version(client);
	if (version >= GNUTLS_DTLS1_2) {
		ret = gnutls_sign_algorithm_get(server);
		if (ret != (int)server_sign_algo) {
			fail("%s: got unexpected server signature algorithm: %d/%s\n", name, ret, gnutls_sign_get_name(ret));
			exit(1);
		}

		ret = gnutls_sign_algorithm_get_client(server);
		if (ret != (int)client_sign_algo) {
			fail("%s: got unexpected client signature algorithm: %d/%s\n", name, ret, gnutls_sign_get_name(ret));
			exit(1);
		}

		ret = gnutls_sign_algorithm_get(client);
		if (ret != (int)server_sign_algo) {
			fail("%s: cl: got unexpected server signature algorithm: %d/%s\n", name, ret, gnutls_sign_get_name(ret));
			exit(1);
		}

		ret = gnutls_sign_algorithm_get_client(client);
		if (ret != (int)client_sign_algo) {
			fail("%s: cl: got unexpected client signature algorithm: %d/%s\n", name, ret, gnutls_sign_get_name(ret));
			exit(1);
		}
	}

	gnutls_record_send(server, MSG, strlen(MSG));

	ret = gnutls_record_recv(client, buffer, sizeof(buffer));
	if (ret == 0) {
		fail("client: Peer has closed the TLS connection\n");
		exit(1);
	} else if (ret < 0) {
		fail("client: Error: %s\n", gnutls_strerror(ret));
		exit(1);
	}

	if (ret != strlen(MSG) || memcmp(MSG, buffer, ret) != 0) {
		fail("client: Error in data received. Expected %d, got %d\n", (int)strlen(MSG), ret);
		exit(1);
	}

	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_anon_free_server_credentials(s_anoncred);
	gnutls_anon_free_client_credentials(c_anoncred);
	gnutls_dh_params_deinit(dh_params);
}
コード例 #5
0
void
doit (void)
{
  /* Server stuff. */
  gnutls_anon_server_credentials_t s_anoncred;
  const gnutls_datum_t p3 = { (char *) pkcs3, strlen (pkcs3) };
  static gnutls_dh_params_t dh_params;
  gnutls_session_t server;
  int sret, cret;
  /* Client stuff. */
  gnutls_anon_client_credentials_t c_anoncred;
  gnutls_session_t client;
  /* Need to enable anonymous KX specifically. */
  char buffer[MAX_BUF + 1];
  ssize_t ns;
  int ret, transferred = 0, msglen;

  /* General init. */
  gnutls_global_init ();
  gnutls_global_set_log_function (tls_log_func);
  if (debug)
    gnutls_global_set_log_level (99);

  /* Init server */
  gnutls_anon_allocate_server_credentials (&s_anoncred);
  gnutls_dh_params_init (&dh_params);
  gnutls_dh_params_import_pkcs3 (dh_params, &p3, GNUTLS_X509_FMT_PEM);
  gnutls_anon_set_server_dh_params (s_anoncred, dh_params);
  gnutls_init (&server, GNUTLS_SERVER|GNUTLS_DATAGRAM|GNUTLS_NONBLOCK);
  ret = gnutls_priority_set_direct (server, "NONE:+VERS-DTLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-DH", NULL);
  if (ret < 0)
    exit(1);
  gnutls_credentials_set (server, GNUTLS_CRD_ANON, s_anoncred);
  gnutls_dh_set_prime_bits (server, 1024);
  gnutls_transport_set_push_function (server, server_push);
  gnutls_transport_set_pull_function (server, server_pull);
  gnutls_transport_set_pull_timeout_function (server, server_pull_timeout_func);
  gnutls_transport_set_ptr (server, (gnutls_transport_ptr_t)server);

  /* Init client */
  gnutls_anon_allocate_client_credentials (&c_anoncred);
  gnutls_init (&client, GNUTLS_CLIENT|GNUTLS_DATAGRAM|GNUTLS_NONBLOCK);
  cret = gnutls_priority_set_direct (client, "NONE:+VERS-DTLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-DH", NULL);
  if (cret < 0)
    exit(1);
  gnutls_credentials_set (client, GNUTLS_CRD_ANON, c_anoncred);
  gnutls_transport_set_push_function (client, client_push);
  gnutls_transport_set_pull_function (client, client_pull);
  gnutls_transport_set_pull_timeout_function (client, client_pull_timeout_func);
  gnutls_transport_set_ptr (client, (gnutls_transport_ptr_t)client);

  handshake = 1;
  HANDSHAKE(client, server);

  handshake = 0;
  if (debug)
    success ("Handshake established\n");

  do
    {
      ret = gnutls_record_send (client, MSG, strlen (MSG));
    }
  while(ret == GNUTLS_E_AGAIN);
  //success ("client: sent %d\n", ns);

  msglen = strlen(MSG);
  TRANSFER(client, server, MSG, msglen, buffer, MAX_BUF);

  if (debug)
    fputs ("\n", stdout);

  gnutls_bye (client, GNUTLS_SHUT_WR);
  gnutls_bye (server, GNUTLS_SHUT_WR);

  gnutls_deinit (client);
  gnutls_deinit (server);

  gnutls_anon_free_client_credentials (c_anoncred);
  gnutls_anon_free_server_credentials (s_anoncred);

  gnutls_dh_params_deinit (dh_params);

  gnutls_global_deinit ();
}
コード例 #6
0
ファイル: anonself.c プロジェクト: sqs/gnutls
static void
server (void)
{
  /* this must be called once in the program
   */
  gnutls_global_init ();

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

  gnutls_anon_allocate_server_credentials (&anoncred);

  if (debug)
    success ("Launched, generating DH parameters...\n");

  generate_dh_params ();

  gnutls_anon_set_server_dh_params (anoncred, dh_params);

  client_len = sizeof (sa_cli);

  session = initialize_tls_session ();

  sd = accept (listen_sd, (SA *) & sa_cli, &client_len);

  if (debug)
    success ("server: connection from %s, port %d\n",
             inet_ntop (AF_INET, &sa_cli.sin_addr, topbuf,
                        sizeof (topbuf)), ntohs (sa_cli.sin_port));

  gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) sd);
  ret = gnutls_handshake (session);
  if (ret < 0)
    {
      close (sd);
      gnutls_deinit (session);
      fail ("server: Handshake has failed (%s)\n\n", gnutls_strerror (ret));
      return;
    }
  if (debug)
    success ("server: Handshake was completed\n");

  if (debug)
    success ("server: TLS version is: %s\n",
             gnutls_protocol_get_name (gnutls_protocol_get_version
                                       (session)));

  /* see the Getting peer's information example */
  /* print_info(session); */

  i = 0;
  for (;;)
    {
      memset (buffer, 0, MAX_BUF + 1);
      ret = gnutls_record_recv (session, buffer, MAX_BUF);

      if (ret == 0)
        {
          if (debug)
            success ("server: Peer has closed the GnuTLS connection\n");
          break;
        }
      else if (ret < 0)
        {
          fail ("server: Received corrupted data(%d). Closing...\n", ret);
          break;
        }
      else if (ret > 0)
        {
          /* echo data back to the client
           */
          gnutls_record_send (session, buffer, strlen (buffer));
        }
    }
  /* do not wait for the peer to close the connection.
   */
  gnutls_bye (session, GNUTLS_SHUT_WR);

  close (sd);
  gnutls_deinit (session);

  close (listen_sd);

  gnutls_anon_free_server_credentials (anoncred);

  gnutls_dh_params_deinit (dh_params);

  gnutls_global_deinit ();

  if (debug)
    success ("server: finished\n");
}
コード例 #7
0
void try_with_key_ks(const char *name, const char *client_prio, gnutls_kx_algorithm_t client_kx,
		gnutls_sign_algorithm_t server_sign_algo,
		gnutls_sign_algorithm_t client_sign_algo,
		const gnutls_datum_t *serv_cert,
		const gnutls_datum_t *serv_key,
		const gnutls_datum_t *client_cert,
		const gnutls_datum_t *client_key,
		unsigned cert_flags,
		unsigned exp_group,
		gnutls_certificate_type_t server_ctype,
		gnutls_certificate_type_t client_ctype)
{
	int ret;
	char buffer[256];
	/* Server stuff. */
	gnutls_certificate_credentials_t server_cred;
	gnutls_anon_server_credentials_t s_anoncred;
	gnutls_dh_params_t dh_params;
	const gnutls_datum_t p3 =
	    { (unsigned char *) pkcs3, strlen(pkcs3) };
	gnutls_session_t server;
	int sret = GNUTLS_E_AGAIN;
	/* Client stuff. */
	gnutls_certificate_credentials_t client_cred;
	gnutls_anon_client_credentials_t c_anoncred;
	gnutls_session_t client;
	int cret = GNUTLS_E_AGAIN, version;
	const char *err;

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

	reset_buffers();
	/* Init server */
	assert(gnutls_anon_allocate_server_credentials(&s_anoncred)>=0);
	assert(gnutls_certificate_allocate_credentials(&server_cred)>=0);

	// Set server crt creds based on ctype
	switch (server_ctype) {
		case GNUTLS_CRT_X509:
			ret = gnutls_certificate_set_x509_key_mem(server_cred,
									serv_cert, serv_key,
									GNUTLS_X509_FMT_PEM);
			break;
		case GNUTLS_CRT_RAWPK:
			ret = gnutls_certificate_set_rawpk_key_mem(server_cred,
									serv_cert, serv_key, GNUTLS_X509_FMT_PEM, NULL, 0,
									NULL, 0, 0);
			break;
		default:
			ret = GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
	}

	if (ret < 0) {
		fail("Could not set key/cert: %s\n", gnutls_strerror(ret));
	}

	gnutls_dh_params_init(&dh_params);
	gnutls_dh_params_import_pkcs3(dh_params, &p3, GNUTLS_X509_FMT_PEM);
	gnutls_certificate_set_dh_params(server_cred, dh_params);
	gnutls_anon_set_server_dh_params(s_anoncred, dh_params);

	assert(gnutls_init(&server, GNUTLS_SERVER | GNUTLS_ENABLE_RAWPK)>=0);
	assert(gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE,
				      server_cred)>=0);
	assert(gnutls_credentials_set(server, GNUTLS_CRD_ANON, s_anoncred)>=0);

	if (server_priority)
		assert(gnutls_priority_set_direct(server, server_priority, NULL) >= 0);
	else
		assert(gnutls_priority_set_direct(server,
				   "NORMAL:+VERS-SSL3.0:+ANON-ECDH:+ANON-DH:+ECDHE-RSA:+DHE-RSA:+RSA:+ECDHE-ECDSA:+CURVE-X25519:+SIGN-EDDSA-ED25519:+CTYPE-ALL",
				   NULL)>=0);
	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(&client_cred);
	if (ret < 0)
		exit(1);

	if (cert_flags == USE_CERT) {
		// Set client crt creds based on ctype
		switch (client_ctype) {
			case GNUTLS_CRT_X509:
				gnutls_certificate_set_x509_key_mem(client_cred,
										client_cert, client_key,
										GNUTLS_X509_FMT_PEM);
				break;
			case GNUTLS_CRT_RAWPK:
				gnutls_certificate_set_rawpk_key_mem(client_cred,
									client_cert, client_key, GNUTLS_X509_FMT_PEM, NULL, 0,
									NULL, 0, 0);
				break;
			default:
				fail("Illegal client certificate type given\n");
		}

		gnutls_certificate_server_set_request(server, GNUTLS_CERT_REQUIRE);
	} else if (cert_flags == ASK_CERT) {
		gnutls_certificate_server_set_request(server, GNUTLS_CERT_REQUEST);
	}

#if 0
	ret = gnutls_certificate_set_x509_trust_mem(client_cred, &ca_cert, GNUTLS_X509_FMT_PEM);
	if (ret < 0)
		exit(1);
#endif
	ret = gnutls_init(&client, GNUTLS_CLIENT | GNUTLS_ENABLE_RAWPK);
	if (ret < 0)
		exit(1);


	assert(gnutls_anon_allocate_client_credentials(&c_anoncred)>=0);
	assert(gnutls_credentials_set(client, GNUTLS_CRD_ANON, c_anoncred)>=0);
	ret = gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE,
				client_cred);
	if (ret < 0)
		exit(1);

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

	ret = gnutls_priority_set_direct(client, client_prio, &err);
	if (ret < 0) {
		if (ret == GNUTLS_E_INVALID_REQUEST)
			fprintf(stderr, "Error in %s\n", err);
		exit(1);
	}
	success("negotiating %s\n", name);
	HANDSHAKE(client, server);

	if (gnutls_kx_get(client) != client_kx) {
		fail("%s: got unexpected key exchange algorithm: %s (expected %s)\n", name, gnutls_kx_get_name(gnutls_kx_get(client)),
			gnutls_kx_get_name(client_kx));
		exit(1);
	}

	/* test signature algorithm match */
	version = gnutls_protocol_get_version(client);
	if (version >= GNUTLS_TLS1_2) {
		ret = gnutls_sign_algorithm_get(server);
		if (ret != (int)server_sign_algo) {
			fail("%s: got unexpected server signature algorithm: %d/%s\n", name, ret, gnutls_sign_get_name(ret));
			exit(1);
		}

		ret = gnutls_sign_algorithm_get_client(server);
		if (ret != (int)client_sign_algo) {
			fail("%s: got unexpected client signature algorithm: %d/%s\n", name, ret, gnutls_sign_get_name(ret));
			exit(1);
		}

		ret = gnutls_sign_algorithm_get(client);
		if (ret != (int)server_sign_algo) {
			fail("%s: cl: got unexpected server signature algorithm: %d/%s\n", name, ret, gnutls_sign_get_name(ret));
			exit(1);
		}

		ret = gnutls_sign_algorithm_get_client(client);
		if (ret != (int)client_sign_algo) {
			fail("%s: cl: got unexpected client signature algorithm: %d/%s\n", name, ret, gnutls_sign_get_name(ret));
			exit(1);
		}
	}

	if (exp_group != 0) {
		ret = gnutls_group_get(server);
		if (ret != (int)exp_group) {
			fail("%s: got unexpected server group: %d/%s\n", name, ret, gnutls_group_get_name(ret));
		}

		ret = gnutls_group_get(client);
		if (ret != (int)exp_group) {
			fail("%s: got unexpected client group: %d/%s\n", name, ret, gnutls_group_get_name(ret));
		}
	}

	gnutls_record_send(server, MSG, strlen(MSG));

	ret = gnutls_record_recv(client, buffer, sizeof(buffer));
	if (ret == 0) {
		fail("client: Peer has closed the TLS connection\n");
		exit(1);
	} else if (ret < 0) {
		fail("client: Error: %s\n", gnutls_strerror(ret));
		exit(1);
	}

	if (ret != strlen(MSG) || memcmp(MSG, buffer, ret) != 0) {
		fail("client: Error in data received. Expected %d, got %d\n", (int)strlen(MSG), ret);
		exit(1);
	}

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

	gnutls_deinit(client);
	gnutls_deinit(server);

	gnutls_certificate_free_credentials(server_cred);
	gnutls_certificate_free_credentials(client_cred);
	gnutls_anon_free_server_credentials(s_anoncred);
	gnutls_anon_free_client_credentials(c_anoncred);
	gnutls_dh_params_deinit(dh_params);
}
コード例 #8
0
anon_server_credentials::anon_server_credentials ():credentials
    (GNUTLS_CRD_ANON)
{
    RETWRAP (gnutls_anon_allocate_server_credentials (&cred));
    set_ptr (cred);
}
コード例 #9
0
ファイル: test.c プロジェクト: jcaose/evcom
int
main (void)
{
  fprintf(stderr, "sizeof(evcom_server): %d\n", (int)sizeof(evcom_server));
  fprintf(stderr, "sizeof(evcom_stream): %d\n", (int)sizeof(evcom_stream));
  fprintf(stderr, "sizeof(evcom_reader): %d\n", (int)sizeof(evcom_reader));
  fprintf(stderr, "sizeof(evcom_writer): %d\n", (int)sizeof(evcom_writer));

  evcom_ignore_sigpipe();

#if EVCOM_HAVE_GNUTLS
  gnutls_global_init();

  gnutls_dh_params_init (&dh_params);

  fsync(fileno(stderr));
  gnutls_dh_params_generate2 (dh_params, DH_BITS);

  gnutls_anon_allocate_server_credentials (&server_credentials);
  gnutls_anon_set_server_dh_params (server_credentials, dh_params);
#endif


  struct sockaddr_in tcp_address;
  memset(&tcp_address, 0, sizeof(struct sockaddr_in));
  tcp_address.sin_family = AF_INET;
  tcp_address.sin_port = htons(PORT);
  tcp_address.sin_addr.s_addr = INADDR_ANY;

  use_tls = 0;

  fprintf(stderr, "pair_pingpong use_pipe=1: ");
  assert(pair_pingpong(1) == 0);
  fprintf(stderr, "\n");

  fprintf(stderr, "pair_pingpong use_pipe=0: ");
  assert(pair_pingpong(0) == 0);
  fprintf(stderr, "\n");

  fprintf(stderr, "zero_stream tcp: ");
  assert(zero_stream((struct sockaddr*)&tcp_address, 5*1024*1024) == 0);
  fprintf(stderr, "\n");

  fprintf(stderr, "pipe_stream: ");
  assert(pipe_stream() == 0);
  fprintf(stderr, "\n");

  fprintf(stderr, "pingpong tcp: ");
  assert(pingpong((struct sockaddr*)&tcp_address) == 0);
  fprintf(stderr, "\n");

  fprintf(stderr, "connint tcp: ");
  assert(connint((struct sockaddr*)&tcp_address) == 0);
  fprintf(stderr, "\n");

#if EVCOM_HAVE_GNUTLS
  use_tls = 1;

  fprintf(stderr, "zero_stream ssl: ");
  assert(zero_stream((struct sockaddr*)&tcp_address, 50*1024) == 0);
  fprintf(stderr, "\n");

  fprintf(stderr, "pair_pingpong ssl use_pipe=1: ");
  assert(pair_pingpong(1) == 0);
  fprintf(stderr, "\n");

  fprintf(stderr, "pair_pingpong ssl use_pipe=0: ");
  assert(pair_pingpong(0) == 0);
  fprintf(stderr, "\n");

  fprintf(stderr, "pingpong ssl: ");
  assert(pingpong((struct sockaddr*)&tcp_address) == 0);
  fprintf(stderr, "\n");

  fprintf(stderr, "connint ssl: ");
  assert(connint((struct sockaddr*)&tcp_address) == 0);
  fprintf(stderr, "\n");

#endif

  struct sockaddr *unix_address;

  use_tls = 0;

  fprintf(stderr, "pingpong unix: ");
  unix_address = create_unix_address();
  assert(pingpong(unix_address) == 0);
  free_unix_address(unix_address);
  fprintf(stderr, "\n");

  fprintf(stderr, "connint unix: ");
  unix_address = create_unix_address();
  assert(connint(unix_address) == 0);
  free_unix_address(unix_address);
  fprintf(stderr, "\n");

#if EVCOM_HAVE_GNUTLS
  use_tls = 1;

  fprintf(stderr, "pingpong unix ssl: ");
  unix_address = create_unix_address();
  assert(pingpong(unix_address) == 0);
  free_unix_address(unix_address);
  fprintf(stderr, "\n");

  fprintf(stderr, "connint unix ssl: ");
  unix_address = create_unix_address();
  assert(connint(unix_address) == 0);
  free_unix_address(unix_address);
  fprintf(stderr, "\n");
#endif

  return 0;
}
コード例 #10
0
ファイル: resume.c プロジェクト: Chronic-Dev/gnutls
static void
server (struct params_res *params)
{
  size_t t;

  /* this must be called once in the program, it is mostly for the server.
   */
  if (debug)
    {
      gnutls_global_set_log_function (tls_log_func);
      gnutls_global_set_log_level (2);
    }

  gnutls_global_init ();
  gnutls_anon_allocate_server_credentials (&anoncred);

  if (debug)
    success ("Launched, generating DH parameters...\n");

  generate_dh_params ();

  gnutls_anon_set_server_dh_params (anoncred, dh_params);

  if (params->enable_db)
    {
      wrap_db_init ();
    }
#ifdef ENABLE_SESSION_TICKET
  if (params->enable_session_ticket_server)
    gnutls_session_ticket_key_generate (&session_ticket_key);
#endif

  for (t = 0; t < 2; t++)
    {
      client_len = sizeof (sa_cli);

      session = initialize_tls_session (params);

      sd = accept (listen_sd, (SA *) & sa_cli, &client_len);

      if (debug)
	success ("server: connection from %s, port %d\n",
		 inet_ntop (AF_INET, &sa_cli.sin_addr, topbuf,
			    sizeof (topbuf)), ntohs (sa_cli.sin_port));

      gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) sd);
      ret = gnutls_handshake (session);
      if (ret < 0)
	{
	  close (sd);
	  gnutls_deinit (session);
	  fail ("server: Handshake has failed (%s)\n\n",
		gnutls_strerror (ret));
	  return;
	}
      if (debug)
	success ("server: Handshake was completed\n");

      /* see the Getting peer's information example */
      /* print_info(session); */

      i = 0;
      for (;;)
	{
	  memset (buffer, 0, MAX_BUF + 1);
	  ret = gnutls_record_recv (session, buffer, MAX_BUF);

	  if (ret == 0)
	    {
	      if (debug)
		success ("server: Peer has closed the GnuTLS connection\n");
	      break;
	    }
	  else if (ret < 0)
	    {
	      fail ("server: Received corrupted data(%d). Closing...\n", ret);
	      break;
	    }
	  else if (ret > 0)
	    {
	      /* echo data back to the client
	       */
	      gnutls_record_send (session, buffer, strlen (buffer));
	    }
	}
      /* do not wait for the peer to close the connection.
       */
      gnutls_bye (session, GNUTLS_SHUT_WR);

      close (sd);

      gnutls_deinit (session);
    }

  close (listen_sd);

  if (params->enable_db)
    {
      wrap_db_deinit ();
    }

  gnutls_free (session_ticket_key.data);
  session_ticket_key.data = NULL;

  if (debug)
    success ("server: finished\n");
}
コード例 #11
0
static void server(int fd)
{
	int ret, csend = 0;
	gnutls_anon_server_credentials_t anoncred;
	char buffer[MAX_BUF + 1];
	gnutls_datum_t cookie_key;
	gnutls_dtls_prestate_st prestate;
	gnutls_session_t session;
	unsigned try = 0;

	/* this must be called once in the program
	 */
	global_init();

	if (debug) {
		gnutls_global_set_log_function(server_log_func);
		gnutls_global_set_log_level(4711);
	}

	ret = gnutls_key_generate(&cookie_key, GNUTLS_COOKIE_KEY_SIZE);
	if (ret < 0) {
		fail("Cannot generate key: %s\n", gnutls_strerror(ret));
		exit(1);
	}

	gnutls_anon_allocate_server_credentials(&anoncred);

	gnutls_init(&session, GNUTLS_SERVER | GNUTLS_DATAGRAM);
	gnutls_handshake_set_timeout(session, SERV_TIMEOUT * 1000);
	gnutls_dtls_set_mtu(session, 1500);

	/* avoid calling all the priority functions, since the defaults
	 * are adequate.
	 */
	gnutls_priority_set_direct(session,
				   "NONE:+VERS-DTLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-ECDH:+CURVE-ALL",
				   NULL);

	gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred);

	gnutls_transport_set_int(session, fd);
	gnutls_transport_set_push_function(session, push);

	for (;;) {
		ret = recv_timeout(fd, buffer, sizeof(buffer), MSG_PEEK, SERV_TIMEOUT);
		if (ret < 0) {
			if (try != 0) {
				success("Server was terminated as expected!\n");
				goto exit;
			} else {
				fail("Error receiving first message\n");
				exit(1);
			}
		}
		try++;

		memset(&prestate, 0, sizeof(prestate));
		prestate.record_seq = 105791312;
		prestate.hsk_write_seq = 67166359;
		ret =
		    gnutls_dtls_cookie_verify(&cookie_key, CLI_ADDR,
					      CLI_ADDR_LEN, buffer, ret,
					      &prestate);
		if (ret < 0) {	/* cookie not valid */
			if (debug)
				success("Sending hello verify request\n");

			ret =
			    gnutls_dtls_cookie_send(&cookie_key, CLI_ADDR,
						    CLI_ADDR_LEN,
						    &prestate,
						    (gnutls_transport_ptr_t)
						    (long) fd, push);
			if (ret < 0) {
				fail("Cannot send data\n");
				exit(1);
			}

			/* discard peeked data */
			recv_timeout(fd, buffer, sizeof(buffer), 0, SERV_TIMEOUT);
			csend++;

			if (csend > 2) {
				fail("too many cookies sent\n");
				exit(1);
			}

			continue;
		}

		/* success */
		break;
	}

	fail("Shouldn't have reached here\n");
	exit(1);
 exit:
	gnutls_deinit(session);
	gnutls_free(cookie_key.data);

	gnutls_anon_free_server_credentials(anoncred);

	gnutls_global_deinit();
}
コード例 #12
0
const struct remote_security_filter *load_security_filter(int tType, const char **dData, load_reference lLoad)
{
	if (initialized) return NULL;

#ifdef HAVE_GCRYPT_H
	if (!gcry_control(GCRYCTL_ANY_INITIALIZATION_P))
	{
	gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);

	gcry_check_version(NULL); //no need to check as of now

	gcry_control(GCRYCTL_DISABLE_SECMEM, 0);
	gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
	}
#endif

	gnutls_global_set_log_function(&gnutls_logging);
	gnutls_global_set_log_level(PARAM_RSVX_TLS_LOGGING);

	gnutls_global_init();

	forwarder_type = tType;

	const char **initializers = dData, **current = initializers;
	int argument_count = 0;

	if (current) while (*current++) argument_count++;

	if (argument_count > 0 && (current = initializers))
	//srp initialization
	{
	use_srp_auth = true;

	const char *passwd          = (*current)? *current++ : NULL;
	const char *srp_passwd      = (*current)? *current++ : NULL;
	const char *srp_passwd_conf = (*current)? *current++ : NULL;

	if (passwd && strlen(passwd))
	 {
	srp_file = passwd;

	if (!parse_passwd())
	  {
	gnutls_global_deinit();
	return NULL;
	  }
	 }

	gnutls_global_init_extra();

	if (srp_passwd && strlen(srp_passwd) && srp_passwd_conf &&
	  strlen(srp_passwd_conf))
	 {
	gnutls_srp_allocate_server_credentials(&srp_server);
	gnutls_srp_set_server_credentials_file(srp_server, srp_passwd,
	  srp_passwd_conf);
	 }
	}

	else
	//anonymouns initialization
	{
	gnutls_anon_allocate_server_credentials(&credentials);

	gnutls_dh_params_init(&dh_params);
	gnutls_dh_params_generate2(dh_params, 1024);

	gnutls_anon_set_server_dh_params(credentials, dh_params);
	}

	return &internal_filter;
}
コード例 #13
0
static void server(int fd)
{
	int ret;
	char buffer[MAX_BUF + 1];
	gnutls_certificate_credentials_t serverx509cred;
	gnutls_anon_server_credentials_t anoncred;
	gnutls_session_t session;
	/* this must be called once in the program
	 */
	global_init();

	if (debug) {
		gnutls_global_set_log_function(server_log_func);
		gnutls_global_set_log_level(4711);
	}

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

	gnutls_init(&session, GNUTLS_SERVER | GNUTLS_DATAGRAM);
	gnutls_dtls_set_mtu(session, MTU);

	/* avoid calling all the priority functions, since the defaults
	 * are adequate.
	 */
	assert(gnutls_priority_set_direct(session,
					  "NONE:+VERS-DTLS-ALL:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ECDHE-RSA:+ANON-ECDH:+CURVE-ALL",
					  NULL) >= 0);

	gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred);
	gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, serverx509cred);

	gnutls_transport_set_int(session, fd);
	gnutls_transport_set_push_function(session, push);

	do {
		ret = gnutls_handshake(session);
	}
	while (ret < 0 && gnutls_error_is_fatal(ret) == 0);
	if (ret < 0) {
		close(fd);
		gnutls_deinit(session);
		fail("server: Handshake has failed (%s)\n\n",
		     gnutls_strerror(ret));
		terminate();
	}
	if (debug)
		success("server: Handshake was completed\n");

	if (debug)
		success("server: TLS version is: %s\n",
			gnutls_protocol_get_name
			(gnutls_protocol_get_version(session)));

	if (gnutls_kx_get(session) != GNUTLS_KX_ANON_ECDH) {
		fail("did not negotiate an anonymous ciphersuite on initial auth\n");
	}

	/* see the Getting peer's information example */
	/* print_info(session); */

	if (debug)
		success("server: Sending dummy packet\n");
	ret = gnutls_rehandshake(session);
	if (ret < 0) {
		fail("gnutls_rehandshake: %s\n", gnutls_strerror(ret));
		terminate();
	}

	if (debug)
		success("server: Initiating rehandshake\n");
	do {
		ret = gnutls_handshake(session);
	}
	while (ret < 0 && gnutls_error_is_fatal(ret) == 0);

	if (ret < 0) {
		fail("server: 2nd gnutls_handshake: %s\n",
		     gnutls_strerror(ret));
		terminate();
	}

	for (;;) {
		memset(buffer, 0, MAX_BUF + 1);

		do {
			ret = gnutls_record_recv(session, buffer, MAX_BUF);
		} while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED);

		if (ret == 0) {
			if (debug)
				success
				    ("server: Peer has closed the GnuTLS connection\n");
			break;
		} else if (ret < 0) {
			fail("server: Received corrupted data(%s). Closing...\n", gnutls_strerror(ret));
			terminate();
		} else if (ret > 0) {
			/* echo data back to the client
			 */
			do {
				ret =
				    gnutls_record_send(session, buffer,
							strlen(buffer));
			} while (ret == GNUTLS_E_AGAIN
				 || ret == GNUTLS_E_INTERRUPTED);
		}
	}

	if (gnutls_kx_get(session) != GNUTLS_KX_ECDHE_RSA) {
		fail("did not negotiate a certificate ciphersuite on second auth\n");
	}

	/* do not wait for the peer to close the connection.
	 */
	gnutls_bye(session, GNUTLS_SHUT_WR);

	close(fd);
	gnutls_deinit(session);

	gnutls_certificate_free_credentials(serverx509cred);
	gnutls_anon_free_server_credentials(anoncred);

	gnutls_global_deinit();

	if (debug)
		success("server: finished\n");
}
コード例 #14
0
static void
server (int fd, int server_init)
{
int ret;
char buffer[MAX_BUF + 1];
  /* this must be called once in the program
   */
  global_init ();

  if (debug)
    {
      gnutls_global_set_log_function (server_log_func);
      gnutls_global_set_log_level (4711);
    }

  gnutls_anon_allocate_server_credentials (&anoncred);

  session = initialize_tls_session ();

  gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) fd);
  gnutls_transport_set_push_function (session, push);

  do 
    {
      ret = gnutls_handshake (session);
    }
  while (ret < 0 && gnutls_error_is_fatal(ret) == 0);
  if (ret < 0)
    {
      close (fd);
      gnutls_deinit (session);
      fail ("server: Handshake has failed (%s)\n\n", gnutls_strerror (ret));
      terminate();
    }
  if (debug)
    success ("server: Handshake was completed\n");

  if (debug)
    success ("server: TLS version is: %s\n",
             gnutls_protocol_get_name (gnutls_protocol_get_version
                                       (session)));

  /* see the Getting peer's information example */
  /* print_info(session); */

  if (server_init)
    {
      if (debug) success("server: Sending dummy packet\n");
      ret = gnutls_rehandshake(session);
      if (ret < 0)
        {
          fail ("gnutls_rehandshake: %s\n", gnutls_strerror(ret));
          terminate();
        }

      if (debug) success("server: Initiating rehandshake\n");
      do 
        {
          ret = gnutls_handshake (session);
        }
      while (ret < 0 && gnutls_error_is_fatal(ret) == 0);

      if (ret < 0)
        {
          fail ("server: 2nd gnutls_handshake: %s\n", gnutls_strerror(ret));
          terminate();
        }
    }

  for (;;)
    {
      memset (buffer, 0, MAX_BUF + 1);

      do {
        ret = gnutls_record_recv (session, buffer, MAX_BUF);
      } while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED);

      if (ret == 0)
        {
          if (debug)
            success ("server: Peer has closed the GnuTLS connection\n");
          break;
        }
      else if (ret < 0)
        {
          if (!server_init && ret == GNUTLS_E_REHANDSHAKE)
            {
              if (debug) success("Initiating rehandshake due to client request\n");
              do 
                {
                  ret = gnutls_handshake (session);
                }
              while (ret < 0 && gnutls_error_is_fatal(ret) == 0);
              if (ret == 0) break;
            }

          fail ("server: Received corrupted data(%s). Closing...\n", gnutls_strerror(ret));
          terminate();
        }
      else if (ret > 0)
        {
          /* echo data back to the client
           */
          do {
            ret = gnutls_record_send (session, buffer, strlen (buffer));
          } while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED);
        }
    }
  

  /* do not wait for the peer to close the connection.
   */
  gnutls_bye (session, GNUTLS_SHUT_WR);

  close (fd);
  gnutls_deinit (session);

  gnutls_anon_free_server_credentials (anoncred);

  gnutls_global_deinit ();

  if (debug)
    success ("server: finished\n");
}