예제 #1
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");
}
예제 #2
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;
}
예제 #3
0
void
doit (void)
{
  int exit_code = EXIT_SUCCESS;
  /* 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;

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

  /* 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_priority_set_direct (server, "NORMAL", NULL);
  gnutls_transport_set_push_function (server, server_push);
  gnutls_transport_set_pull_function (server, server_pull);
  gnutls_transport_set_ptr (server, (gnutls_transport_ptr_t)server);

  /* Init client */
  gnutls_certificate_allocate_credentials (&clientx509cred);
  gnutls_init (&client, GNUTLS_CLIENT);
  gnutls_credentials_set (client, GNUTLS_CRD_CERTIFICATE, clientx509cred);
  gnutls_priority_set_direct (client, "NORMAL", NULL);
  gnutls_transport_set_push_function (client, client_push);
  gnutls_transport_set_pull_function (client, client_pull);
  gnutls_transport_set_ptr (client, (gnutls_transport_ptr_t)client);

  HANDSHAKE(client, server);

  sret = gnutls_rehandshake (server);
  if (debug)
    {
      tls_log_func (0, "gnutls_rehandshake (server)...\n");
      tls_log_func (0, gnutls_strerror (sret));
      tls_log_func (0, "\n");
    }

  {
    ssize_t n;
    char b[1];
    n = gnutls_record_recv (client, b, 1);
    if (n != GNUTLS_E_REHANDSHAKE)
      abort ();
  }

  HANDSHAKE(client, server);

  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)
    {
      if (exit_code == 0)
        puts ("Self-test successful");
      else
        puts ("Self-test failed");
    }
}
예제 #4
0
static void server(int sds[])
{
	int j;
	/* this must be called once in the program
	 */
	global_init();

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

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

	generate_dh_params();

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

		if (j == 0) {
			gnutls_certificate_allocate_credentials(&pgp_cred);
			ret =
			    gnutls_certificate_set_openpgp_key_mem2
			    (pgp_cred, &server_crt, &server_key, "auto",
			     GNUTLS_OPENPGP_FMT_BASE64);
		} else {
			gnutls_certificate_free_credentials(pgp_cred);
			gnutls_certificate_allocate_credentials(&pgp_cred);
			ret =
			    gnutls_certificate_set_openpgp_key_mem2
			    (pgp_cred, &cert2048, &key2048, "auto",
			     GNUTLS_OPENPGP_FMT_BASE64);
		}

		if (ret < 0) {
			fail("Could not set server key files...\n");
			goto end;
		}

		gnutls_certificate_set_dh_params(pgp_cred, dh_params);

		session = initialize_tls_session();

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

		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 */
		if (debug)
			print_info(session);

		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);
				goto end;
			} 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);
	}

      end:
	gnutls_certificate_free_credentials(pgp_cred);

	gnutls_dh_params_deinit(dh_params);

	gnutls_global_deinit();

	if (debug)
		success("server: finished\n");
}
예제 #5
0
static void ekg_gnutls_free_connection(struct ekg_gnutls_connection *conn) {
	gnutls_deinit(conn->session);
	gnutls_certificate_free_credentials(conn->cred);
	g_slice_free(struct ekg_gnutls_connection, conn);
}
예제 #6
0
파일: ssl_gnutls.c 프로젝트: darnir/neomutt
/**
 * tls_negotiate - Negotiate TLS connection
 * @param conn Connection to a server
 * @retval  0 Success
 * @retval -1 Error
 *
 * After TLS state has been initialized, attempt to negotiate TLS over the
 * wire, including certificate checks.
 */
static int tls_negotiate(struct Connection *conn)
{
  struct TlsSockData *data = mutt_mem_calloc(1, sizeof(struct TlsSockData));
  conn->sockdata = data;
  int err = gnutls_certificate_allocate_credentials(&data->xcred);
  if (err < 0)
  {
    FREE(&conn->sockdata);
    mutt_error("gnutls_certificate_allocate_credentials: %s", gnutls_strerror(err));
    return -1;
  }

  gnutls_certificate_set_x509_trust_file(data->xcred, C_CertificateFile, GNUTLS_X509_FMT_PEM);
  /* ignore errors, maybe file doesn't exist yet */

  if (C_SslCaCertificatesFile)
  {
    gnutls_certificate_set_x509_trust_file(data->xcred, C_SslCaCertificatesFile,
                                           GNUTLS_X509_FMT_PEM);
  }

  if (C_SslClientCert)
  {
    mutt_debug(LL_DEBUG2, "Using client certificate %s\n", C_SslClientCert);
    gnutls_certificate_set_x509_key_file(data->xcred, C_SslClientCert,
                                         C_SslClientCert, GNUTLS_X509_FMT_PEM);
  }

#ifdef HAVE_DECL_GNUTLS_VERIFY_DISABLE_TIME_CHECKS
  /* disable checking certificate activation/expiration times
   * in gnutls, we do the checks ourselves */
  gnutls_certificate_set_verify_flags(data->xcred, GNUTLS_VERIFY_DISABLE_TIME_CHECKS);
#endif

  err = gnutls_init(&data->state, GNUTLS_CLIENT);
  if (err)
  {
    mutt_error("gnutls_handshake: %s", gnutls_strerror(err));
    goto fail;
  }

  /* set socket */
  gnutls_transport_set_ptr(data->state, (gnutls_transport_ptr_t)(long) conn->fd);

  if (gnutls_server_name_set(data->state, GNUTLS_NAME_DNS, conn->account.host,
                             mutt_str_strlen(conn->account.host)))
  {
    mutt_error(_("Warning: unable to set TLS SNI host name"));
  }

  if (tls_set_priority(data) < 0)
  {
    goto fail;
  }

  if (C_SslMinDhPrimeBits > 0)
  {
    gnutls_dh_set_prime_bits(data->state, C_SslMinDhPrimeBits);
  }

  /* gnutls_set_cred (data->state, GNUTLS_ANON, NULL); */

  gnutls_credentials_set(data->state, GNUTLS_CRD_CERTIFICATE, data->xcred);

  err = gnutls_handshake(data->state);

  while (err == GNUTLS_E_AGAIN)
  {
    err = gnutls_handshake(data->state);
  }
  if (err < 0)
  {
    if (err == GNUTLS_E_FATAL_ALERT_RECEIVED)
    {
      mutt_error("gnutls_handshake: %s(%s)", gnutls_strerror(err),
                 gnutls_alert_get_name(gnutls_alert_get(data->state)));
    }
    else
    {
      mutt_error("gnutls_handshake: %s", gnutls_strerror(err));
    }
    goto fail;
  }

  if (tls_check_certificate(conn) == 0)
    goto fail;

  /* set Security Strength Factor (SSF) for SASL */
  /* NB: gnutls_cipher_get_key_size() returns key length in bytes */
  conn->ssf = gnutls_cipher_get_key_size(gnutls_cipher_get(data->state)) * 8;

  tls_get_client_cert(conn);

  if (!OptNoCurses)
  {
    mutt_message(_("SSL/TLS connection using %s (%s/%s/%s)"),
                 gnutls_protocol_get_name(gnutls_protocol_get_version(data->state)),
                 gnutls_kx_get_name(gnutls_kx_get(data->state)),
                 gnutls_cipher_get_name(gnutls_cipher_get(data->state)),
                 gnutls_mac_get_name(gnutls_mac_get(data->state)));
    mutt_sleep(0);
  }

  return 0;

fail:
  gnutls_certificate_free_credentials(data->xcred);
  gnutls_deinit(data->state);
  FREE(&conn->sockdata);
  return -1;
}
예제 #7
0
int main(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 };

	gnutls_global_init();

	gnutls_anon_allocate_client_credentials(&anoncred);

	/* 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);

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

	gnutls_transport_set_ptr(session, (gnutls_transport_ptr_t) sd);

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

	if(ret < 0) {
		fprintf(stderr, "*** Handshake failed\n");
		gnutls_perror(ret);
		goto end;
	} else {
		printf("- Handshake was completed\n");
	}

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

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

	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);

	gnutls_global_deinit();

	return 0;
}
예제 #8
0
void try_with_key_fail(const char *name, const char *client_prio,
			int server_err, int client_err,
			const gnutls_datum_t *serv_cert,
			const gnutls_datum_t *serv_key,
			const gnutls_datum_t *cli_cert,
			const gnutls_datum_t *cli_key)
{
	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;
	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_certificate_allocate_credentials(&serverx509cred)>=0);

	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));

	assert(gnutls_init(&server, GNUTLS_SERVER)>=0);
	if (server_priority)
		assert(gnutls_priority_set_direct(server, server_priority, NULL) >= 0);
	else
		assert(gnutls_priority_set_direct(server, client_prio, NULL) >= 0);

	assert(gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE,
				      serverx509cred)>=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(&clientx509cred);
	if (ret < 0)
		exit(1);

	if (cli_cert) {
		gnutls_certificate_set_x509_key_mem(clientx509cred,
						    cli_cert, cli_key,
						    GNUTLS_X509_FMT_PEM);
		gnutls_certificate_server_set_request(server, GNUTLS_CERT_REQUIRE);
	}

	ret = gnutls_init(&client, GNUTLS_CLIENT);
	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);
	}

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

	success("negotiating %s\n", name);
	HANDSHAKE_EXPECT(client, server, client_err, server_err);

	gnutls_deinit(client);
	gnutls_deinit(server);

	gnutls_certificate_free_credentials(serverx509cred);
	gnutls_certificate_free_credentials(clientx509cred);
}
예제 #9
0
static void server(int fd)
{
	int ret;
	char buffer[MAX_BUF + 1];
	gnutls_session_t session;
	gnutls_certificate_credentials_t x509_cred;
	gnutls_datum_t skey;

	/* 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);
	}

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

	assert(gnutls_init(&session, GNUTLS_SERVER)>=0);

	assert(gnutls_session_ticket_key_generate(&skey)>=0);
	assert(gnutls_session_ticket_enable_server(session, &skey) >= 0);

	gnutls_handshake_set_hook_function(session, GNUTLS_HANDSHAKE_NEW_SESSION_TICKET,
					   GNUTLS_HOOK_POST,
					   handshake_callback);

	/* avoid calling all the priority functions, since the defaults
	 * are adequate.
	 */
	assert(gnutls_priority_set_direct(session, "NORMAL", NULL)>=0);

	gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred);

	gnutls_transport_set_int(session, fd);

	do {
		ret = gnutls_handshake(session);
	} while (ret < 0 && gnutls_error_is_fatal(ret) == 0);
	if (ret < 0) {
		/* failure is expected here */
		goto end;
	}

	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 (sent != 0) {
		fail("new session ticket was sent\n");
		exit(1);
	}		

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

 end:
	close(fd);
	gnutls_deinit(session);
	gnutls_free(skey.data);

	gnutls_certificate_free_credentials(x509_cred);

	gnutls_global_deinit();

	if (debug)
		success("server: finished\n");
}
예제 #10
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);
}
예제 #11
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);
}
예제 #12
0
static void server(int fd, unsigned do_fork)
{
	int ret;
	gnutls_certificate_credentials_t x509_cred;
	gnutls_session_t session;

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

#if 0
	if (debug) {
		side = "server";
		gnutls_global_set_log_function(tls_log_func);
		gnutls_global_set_log_level(4711);
	}
#endif

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

	gnutls_init(&session, GNUTLS_SERVER | GNUTLS_DATAGRAM);
	gnutls_dtls_set_timeouts(session, 5 * 1000, 60 * 1000);
	gnutls_dtls_set_mtu(session, 400);

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

	gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred);

	gnutls_transport_set_int(session, 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)));

	if (do_fork)
		do_fork_stuff(session);
	else
		do_reflect_stuff(session);


	close(fd);
	gnutls_deinit(session);

	gnutls_certificate_free_credentials(x509_cred);

	gnutls_global_deinit();

	if (debug)
		success("server: finished\n");
}
예제 #13
0
static void client(int fd, unsigned do_fork)
{
	int ret;
	gnutls_certificate_credentials_t x509_cred;
	gnutls_session_t session;
	/* Need to enable anonymous KX specifically. */

	global_init();

	if (debug) {
		side = "client";
		gnutls_global_set_log_function(tls_log_func);
		gnutls_global_set_log_level(4711);
	}

	gnutls_certificate_allocate_credentials(&x509_cred);

	/* Initialize TLS session
	 */
	gnutls_init(&session, GNUTLS_CLIENT | GNUTLS_DATAGRAM);
	gnutls_dtls_set_mtu(session, 1500);
	gnutls_dtls_set_timeouts(session, 6 * 1000, 60 * 1000);
	//gnutls_transport_set_push_function(session, push);

	/* Use default priorities */
	gnutls_priority_set_direct(session,
				   "NONE:+VERS-DTLS-ALL:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ECDHE-ECDSA:+CURVE-ALL",
				   NULL);

	/* put the anonymous credentials to the current session
	 */
	gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred);

	gnutls_transport_set_int(session, fd);

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

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

	if (do_fork)
		do_fork_stuff(session);
	else
		do_reflect_stuff(session);

	close(fd);

	gnutls_deinit(session);

	gnutls_certificate_free_credentials(x509_cred);

	gnutls_global_deinit();
	exit(0);
}
예제 #14
0
void doit(void)
{
	int err, i;
	int sockets[2];
	const char *srcdir;
	pid_t child;
	char pub_key_path[512], priv_key_path[512];

	global_init();

	srcdir = getenv("srcdir") ? getenv("srcdir") : ".";

	for (i = 0; i < 5; i++) {
		if (i <= 1)
			key_id = NULL;	/* try using the master key */
		else if (i == 2)
			key_id = "auto";	/* test auto */
		else if (i >= 3)
			key_id = "f30fd423c143e7ba";

		if (debug) {
			gnutls_global_set_log_level(5);
			gnutls_global_set_log_function(log_message);
		}

		err = socketpair(AF_UNIX, SOCK_STREAM, 0, sockets);
		if (err != 0)
			fail("socketpair %s\n", strerror(errno));

		if (sizeof(pub_key_path) <
		    strlen(srcdir) + strlen(pub_key_file) + 2)
			abort();

		strcpy(pub_key_path, srcdir);
		strcat(pub_key_path, "/");
		strcat(pub_key_path, pub_key_file);

		if (sizeof(priv_key_path) <
		    strlen(srcdir) + strlen(priv_key_file) + 2)
			abort();

		strcpy(priv_key_path, srcdir);
		strcat(priv_key_path, "/");
		strcat(priv_key_path, priv_key_file);

		child = fork();
		if (child == -1)
			fail("fork %s\n", strerror(errno));

		if (child == 0) {
			/* Child process (client).  */
			gnutls_session_t session;
			gnutls_certificate_credentials_t cred;
			ssize_t sent;

			if (debug)
				printf("client process %i\n", getpid());

			err = gnutls_init(&session, GNUTLS_CLIENT);
			if (err != 0)
				fail("client session %d\n", err);

			if (i == 0)	/* we use the primary key which is RSA. Test the RSA ciphersuite */
				gnutls_priority_set_direct(session,
							   "NONE:+VERS-TLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+RSA:+CTYPE-OPENPGP",
							   NULL);
			else
				gnutls_priority_set_direct(session,
							   "NONE:+VERS-TLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+DHE-DSS:+DHE-RSA:+CTYPE-OPENPGP",
							   NULL);
			gnutls_transport_set_int(session, sockets[0]);

			err =
			    gnutls_certificate_allocate_credentials(&cred);
			if (err != 0)
				fail("client credentials %d\n", err);

			err =
			    gnutls_certificate_set_openpgp_key_file2(cred,
								     pub_key_path,
								     priv_key_path,
								     key_id,
								     GNUTLS_OPENPGP_FMT_BASE64);
			if (err != 0)
				fail("client openpgp keys %s\n",
				     gnutls_strerror(err));

			check_loaded_key(cred);

			err =
			    gnutls_credentials_set(session,
						   GNUTLS_CRD_CERTIFICATE,
						   cred);
			if (err != 0)
				fail("client credential_set %d\n", err);

			gnutls_dh_set_prime_bits(session, 1024);

			if (i == 4)
				gnutls_openpgp_send_cert(session,
							 GNUTLS_OPENPGP_CERT_FINGERPRINT);

			err = gnutls_handshake(session);
			if (err != 0)
				fail("client handshake %s (%d) \n",
				     gnutls_strerror(err), err);
			else if (debug)
				printf("client handshake successful\n");

			sent =
			    gnutls_record_send(session, message,
						sizeof(message));
			if (sent != sizeof(message))
				fail("client sent %li vs. %li\n",
				     (long) sent, (long) sizeof(message));

			err = gnutls_bye(session, GNUTLS_SHUT_RDWR);
			if (err != 0)
				fail("client bye %d\n", err);

			if (debug)
				printf("client done\n");

			gnutls_deinit(session);
			gnutls_certificate_free_credentials(cred);
			gnutls_free(stored_cli_cert.data);
			gnutls_global_deinit();
			return;
		} else {
			/* Parent process (server).  */
			gnutls_session_t session;
			gnutls_dh_params_t dh_params;
			gnutls_certificate_credentials_t cred;
			char greetings[sizeof(message) * 2];
			ssize_t received;
			pid_t done;
			int status;
			const gnutls_datum_t p3 =
			    { (void *) pkcs3, strlen(pkcs3) };

			if (debug)
				printf("server process %i (child %i)\n",
					getpid(), child);

			err = gnutls_init(&session, GNUTLS_SERVER);
			if (err != 0)
				fail("server session %d\n", err);

			gnutls_priority_set_direct(session,
						   "NONE:+VERS-TLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+DHE-DSS:+DHE-RSA:+RSA:+CTYPE-OPENPGP",
						   NULL);
			gnutls_transport_set_int(session, sockets[1]);

			err =
			    gnutls_certificate_allocate_credentials(&cred);
			if (err != 0)
				fail("server credentials %d\n", err);

			err =
			    gnutls_certificate_set_openpgp_key_file2(cred,
								     pub_key_path,
								     priv_key_path,
								     key_id,
								     GNUTLS_OPENPGP_FMT_BASE64);
			if (err != 0)
				fail("server openpgp keys %s\n",
				     gnutls_strerror(err));

			check_loaded_key(cred);

			err = gnutls_dh_params_init(&dh_params);
			if (err)
				fail("server DH params init %d\n", err);

			err =
			    gnutls_dh_params_import_pkcs3(dh_params, &p3,
							  GNUTLS_X509_FMT_PEM);
			if (err)
				fail("server DH params generate %d\n",
				     err);

			gnutls_certificate_set_dh_params(cred, dh_params);

			err =
			    gnutls_credentials_set(session,
						   GNUTLS_CRD_CERTIFICATE,
						   cred);
			if (err != 0)
				fail("server credential_set %d\n", err);

			gnutls_certificate_server_set_request(session,
							      GNUTLS_CERT_REQUIRE);

			if (i == 4)
				gnutls_openpgp_set_recv_key_function
				    (session, key_recv_func);

			err = gnutls_handshake(session);
			if (err != 0)
				fail("server handshake %s (%d) \n",
				     gnutls_strerror(err), err);

			if (stored_cli_cert.data == NULL) {
				const gnutls_datum_t *d;
				unsigned int d_size;
				d = gnutls_certificate_get_peers(session,
								 &d_size);
				if (d != NULL) {
					stored_cli_cert.data =
					    gnutls_malloc(d[0].size);
					memcpy(stored_cli_cert.data,
						d[0].data, d[0].size);
					stored_cli_cert.size = d[0].size;
				}
			}

			received =
			    gnutls_record_recv(session, greetings,
						sizeof(greetings));
			if (received != sizeof(message)
			    || memcmp(greetings, message, sizeof(message)))
				fail("server received %li vs. %li\n",
				     (long) received,
				     (long) sizeof(message));

			err = gnutls_bye(session, GNUTLS_SHUT_RDWR);
			if (err != 0)
				fail("server bye %s (%d) \n",
				     gnutls_strerror(err), err);

			if (debug)
				printf("server done\n");

			gnutls_deinit(session);
			gnutls_certificate_free_credentials(cred);
			gnutls_dh_params_deinit(dh_params);

			done = wait(&status);
			if (done < 0)
				fail("wait %s\n", strerror(errno));

			if (done != child)
				fail("who's that?! %d\n", done);

			check_wait_status(status);
		}
	}

	gnutls_free(stored_cli_cert.data);
	gnutls_global_deinit();
}
예제 #15
0
파일: mini.c 프로젝트: Chronic-Dev/gnutls
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);

  /* 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);

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

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

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

  ns = gnutls_record_send (client, MSG, strlen (MSG));
  if (debug)
    success ("client: sent %d\n", (int) 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
    {
      if (debug)
	{
	  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));
  if (debug)
    success ("server: sent %d\n", (int) 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
    {
      if (debug)
	{
	  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 ();
}
예제 #16
0
static void client(int fd)
{
	int ret;
	gnutls_certificate_credentials_t x509_cred;
	gnutls_session_t session;
	/* Need to enable anonymous KX specifically. */

	gnutls_global_set_time_function(mytime);
	global_init();

	if (debug) {
		gnutls_global_set_log_function(client_log_func);
		gnutls_global_set_log_level(7);
	}

	gnutls_certificate_allocate_credentials(&x509_cred);

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

	/* Use default priorities */
	gnutls_priority_set_direct(session, "NORMAL:-KX-ALL:+ECDHE-RSA", NULL);

	/* put the anonymous credentials to the current session
	 */
	gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred);

	gnutls_transport_set_int(session, fd);

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

	if (ret == GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM) {
		/* success */
		goto end;
	}

	if (ret < 0) {
		fail("client: Handshake failed: %s\n", gnutls_strerror(ret));
		terminate();
	} else {
		if (debug)
			success("client: Handshake was completed\n");
	}

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

	gnutls_bye(session, GNUTLS_SHUT_WR);

      end:

	close(fd);

	gnutls_deinit(session);

	gnutls_certificate_free_credentials(x509_cred);

	gnutls_global_deinit();
}
예제 #17
0
파일: cli.c 프로젝트: philippe-goetz/gnutls
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]);
  cmd_parser (argc, argv);

  gnutls_global_set_log_function (tls_log_func);
  gnutls_global_set_log_level (OPT_VALUE_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 ();

  init_global_tls_stuff ();

  socket_open (&hd, hostname, service, udp);
  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);

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

          printf
            ("\n\n- Connecting again- trying to resume previous session\n");
          socket_open (&hd, hostname, service, udp);
          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;
}
예제 #18
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 ();
}
예제 #19
0
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();
}
예제 #20
0
SslSocket::~SslSocket()
{
	TRACE("~SslSocket()");
	gnutls_deinit(session_);
}
예제 #21
0
static void client(int sds[])
{
	int ret, ii, j;
	gnutls_session_t session;
	char buffer[MAX_BUF + 1];
	gnutls_certificate_credentials_t xcred;

	global_init();

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

	gnutls_certificate_allocate_credentials(&xcred);

	/* sets the trusted cas file
	 */
	if (debug)
		success("Setting key files...\n");

	ret = gnutls_certificate_set_openpgp_key_mem(xcred, &cert, &key,
						     GNUTLS_OPENPGP_FMT_BASE64);
	if (ret < 0) {
		fail("Could not set key files...\n");
		return;
	}

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

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

		/* Use default priorities */
		gnutls_priority_set_direct(session,
					   "NORMAL:+CTYPE-OPENPGP:+DHE-DSS:+DHE-DSS:+SIGN-DSA-SHA1:+SIGN-DSA-SHA256", NULL);

		/* put the x509 credentials to the current session
		 */
		gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
					xcred);

		gnutls_transport_set_int(session, sd);

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

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

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

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

		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_certificate_free_credentials(xcred);

	gnutls_global_deinit();
}
예제 #22
0
static int setup_dtls_connection(struct worker_st *ws)
{
	int ret;
	gnutls_session_t session;
	gnutls_datum_t master =
	    { ws->master_secret, sizeof(ws->master_secret) };
	gnutls_datum_t sid = { ws->session_id, sizeof(ws->session_id) };

	if (ws->req.selected_ciphersuite == NULL) {
		oclog(ws, LOG_ERR, "no DTLS ciphersuite negotiated");
		return -1;
	}

	oclog(ws, LOG_DEBUG, "setting up DTLS connection");
	/* DTLS cookie verified.
	 * Initialize session.
	 */
	ret = gnutls_init(&session, GNUTLS_SERVER|GNUTLS_DATAGRAM|GNUTLS_NONBLOCK);
	if (ret < 0) {
		oclog(ws, LOG_ERR, "could not initialize TLS session: %s",
		      gnutls_strerror(ret));
		return -1;
	}

	ret =
	    gnutls_priority_set_direct(session,
				       ws->req.
				       selected_ciphersuite->gnutls_name, NULL);
	if (ret < 0) {
		oclog(ws, LOG_ERR, "could not set TLS priority: %s",
		      gnutls_strerror(ret));
		goto fail;
	}

	ret = gnutls_session_set_premaster(session, GNUTLS_SERVER,
					   ws->req.
					   selected_ciphersuite->gnutls_version,
					   GNUTLS_KX_RSA,
					   ws->req.
					   selected_ciphersuite->gnutls_cipher,
					   ws->req.
					   selected_ciphersuite->gnutls_mac,
					   GNUTLS_COMP_NULL, &master, &sid);
	if (ret < 0) {
		oclog(ws, LOG_ERR, "could not set TLS premaster: %s",
		      gnutls_strerror(ret));
		goto fail;
	}

	ret =
	    gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
				   ws->creds->xcred);
	if (ret < 0) {
		oclog(ws, LOG_ERR, "could not set TLS credentials: %s",
		      gnutls_strerror(ret));
		goto fail;
	}

	gnutls_transport_set_push_function(session, dtls_push);
	gnutls_transport_set_pull_function(session, dtls_pull);
	gnutls_transport_set_pull_timeout_function(session, dtls_pull_timeout);
	gnutls_transport_set_ptr(session, &ws->dtls_tptr);

	gnutls_session_set_ptr(session, ws);
	gnutls_certificate_server_set_request(session, GNUTLS_CERT_IGNORE);

	gnutls_handshake_set_timeout(session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);

	ws->udp_state = UP_HANDSHAKE;

	ws->dtls_session = session;

	return 0;
 fail:
	gnutls_deinit(session);
	return -1;
}
예제 #23
0
int					/* O - 0 on success, -1 on failure */
_httpTLSStart(http_t *http)		/* I - Connection to server */
{
  char			hostname[256],	/* Hostname */
			*hostptr;	/* Pointer into hostname */
  int			status;		/* Status of handshake */
  gnutls_certificate_credentials_t *credentials;
					/* TLS credentials */
  char			priority_string[1024];
					/* Priority string */


  DEBUG_printf(("3_httpTLSStart(http=%p)", http));

  if (tls_options < 0)
  {
    DEBUG_puts("4_httpTLSStart: Setting defaults.");
    _cupsSetDefaults();
    DEBUG_printf(("4_httpTLSStart: tls_options=%x", tls_options));
  }

  if (http->mode == _HTTP_MODE_SERVER && !tls_keypath)
  {
    DEBUG_puts("4_httpTLSStart: cupsSetServerCredentials not called.");
    http->error  = errno = EINVAL;
    http->status = HTTP_STATUS_ERROR;
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Server credentials not set."), 1);

    return (-1);
  }

  credentials = (gnutls_certificate_credentials_t *)
                    malloc(sizeof(gnutls_certificate_credentials_t));
  if (credentials == NULL)
  {
    DEBUG_printf(("8_httpStartTLS: Unable to allocate credentials: %s",
                  strerror(errno)));
    http->error  = errno;
    http->status = HTTP_STATUS_ERROR;
    _cupsSetHTTPError(HTTP_STATUS_ERROR);

    return (-1);
  }

  gnutls_certificate_allocate_credentials(credentials);
  status = gnutls_init(&http->tls, http->mode == _HTTP_MODE_CLIENT ? GNUTLS_CLIENT : GNUTLS_SERVER);
  if (!status)
    status = gnutls_set_default_priority(http->tls);

  if (status)
  {
    http->error  = EIO;
    http->status = HTTP_STATUS_ERROR;

    DEBUG_printf(("4_httpTLSStart: Unable to initialize common TLS parameters: %s", gnutls_strerror(status)));
    _cupsSetError(IPP_STATUS_ERROR_CUPS_PKI, gnutls_strerror(status), 0);

    gnutls_deinit(http->tls);
    gnutls_certificate_free_credentials(*credentials);
    free(credentials);
    http->tls = NULL;

    return (-1);
  }

  if (http->mode == _HTTP_MODE_CLIENT)
  {
   /*
    * Client: get the hostname to use for TLS...
    */

    if (httpAddrLocalhost(http->hostaddr))
    {
      strlcpy(hostname, "localhost", sizeof(hostname));
    }
    else
    {
     /*
      * Otherwise make sure the hostname we have does not end in a trailing dot.
      */

      strlcpy(hostname, http->hostname, sizeof(hostname));
      if ((hostptr = hostname + strlen(hostname) - 1) >= hostname &&
	  *hostptr == '.')
	*hostptr = '\0';
    }

    status = gnutls_server_name_set(http->tls, GNUTLS_NAME_DNS, hostname, strlen(hostname));
  }
  else
  {
   /*
    * Server: get certificate and private key...
    */

    char	crtfile[1024],		/* Certificate file */
		keyfile[1024];		/* Private key file */
    int		have_creds = 0;		/* Have credentials? */

    if (http->fields[HTTP_FIELD_HOST][0])
    {
     /*
      * Use hostname for TLS upgrade...
      */

      strlcpy(hostname, http->fields[HTTP_FIELD_HOST], sizeof(hostname));
    }
    else
    {
     /*
      * Resolve hostname from connection address...
      */

      http_addr_t	addr;		/* Connection address */
      socklen_t		addrlen;	/* Length of address */

      addrlen = sizeof(addr);
      if (getsockname(http->fd, (struct sockaddr *)&addr, &addrlen))
      {
	DEBUG_printf(("4_httpTLSStart: Unable to get socket address: %s", strerror(errno)));
	hostname[0] = '\0';
      }
      else if (httpAddrLocalhost(&addr))
	hostname[0] = '\0';
      else
      {
	httpAddrLookup(&addr, hostname, sizeof(hostname));
        DEBUG_printf(("4_httpTLSStart: Resolved socket address to \"%s\".", hostname));
      }
    }

    if (isdigit(hostname[0] & 255) || hostname[0] == '[')
      hostname[0] = '\0';		/* Don't allow numeric addresses */

    if (hostname[0])
    {
      http_gnutls_make_path(crtfile, sizeof(crtfile), tls_keypath, hostname, "crt");
      http_gnutls_make_path(keyfile, sizeof(keyfile), tls_keypath, hostname, "key");

      have_creds = !access(crtfile, 0) && !access(keyfile, 0);
    }
    else if (tls_common_name)
    {
      http_gnutls_make_path(crtfile, sizeof(crtfile), tls_keypath, tls_common_name, "crt");
      http_gnutls_make_path(keyfile, sizeof(keyfile), tls_keypath, tls_common_name, "key");

      have_creds = !access(crtfile, 0) && !access(keyfile, 0);
    }

    if (!have_creds && tls_auto_create && (hostname[0] || tls_common_name))
    {
      DEBUG_printf(("4_httpTLSStart: Auto-create credentials for \"%s\".", hostname[0] ? hostname : tls_common_name));

      if (!cupsMakeServerCredentials(tls_keypath, hostname[0] ? hostname : tls_common_name, 0, NULL, time(NULL) + 365 * 86400))
      {
	DEBUG_puts("4_httpTLSStart: cupsMakeServerCredentials failed.");
	http->error  = errno = EINVAL;
	http->status = HTTP_STATUS_ERROR;
	_cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Unable to create server credentials."), 1);

	return (-1);
      }
    }

    DEBUG_printf(("4_httpTLSStart: Using certificate \"%s\" and private key \"%s\".", crtfile, keyfile));

    status = gnutls_certificate_set_x509_key_file(*credentials, crtfile, keyfile, GNUTLS_X509_FMT_PEM);
  }

  if (!status)
    status = gnutls_credentials_set(http->tls, GNUTLS_CRD_CERTIFICATE, *credentials);

  if (status)
  {
    http->error  = EIO;
    http->status = HTTP_STATUS_ERROR;

    DEBUG_printf(("4_httpTLSStart: Unable to complete client/server setup: %s", gnutls_strerror(status)));
    _cupsSetError(IPP_STATUS_ERROR_CUPS_PKI, gnutls_strerror(status), 0);

    gnutls_deinit(http->tls);
    gnutls_certificate_free_credentials(*credentials);
    free(credentials);
    http->tls = NULL;

    return (-1);
  }

  strlcpy(priority_string, "NORMAL", sizeof(priority_string));

  if (tls_options & _HTTP_TLS_DENY_TLS10)
    strlcat(priority_string, ":+VERS-TLS-ALL:-VERS-TLS1.0:-VERS-SSL3.0", sizeof(priority_string));
  else if (tls_options & _HTTP_TLS_ALLOW_SSL3)
    strlcat(priority_string, ":+VERS-TLS-ALL", sizeof(priority_string));
  else
    strlcat(priority_string, ":+VERS-TLS-ALL:-VERS-SSL3.0", sizeof(priority_string));

  if (!(tls_options & _HTTP_TLS_ALLOW_RC4))
    strlcat(priority_string, ":-ARCFOUR-128", sizeof(priority_string));

  if (!(tls_options & _HTTP_TLS_ALLOW_DH))
    strlcat(priority_string, ":!ANON-DH", sizeof(priority_string));

#ifdef HAVE_GNUTLS_PRIORITY_SET_DIRECT
  gnutls_priority_set_direct(http->tls, priority_string, NULL);

#else
  gnutls_priority_t priority;		/* Priority */

  gnutls_priority_init(&priority, priority_string, NULL);
  gnutls_priority_set(http->tls, priority);
  gnutls_priority_deinit(priority);
#endif /* HAVE_GNUTLS_PRIORITY_SET_DIRECT */

  gnutls_transport_set_ptr(http->tls, (gnutls_transport_ptr_t)http);
  gnutls_transport_set_pull_function(http->tls, http_gnutls_read);
#ifdef HAVE_GNUTLS_TRANSPORT_SET_PULL_TIMEOUT_FUNCTION
  gnutls_transport_set_pull_timeout_function(http->tls, (gnutls_pull_timeout_func)httpWait);
#endif /* HAVE_GNUTLS_TRANSPORT_SET_PULL_TIMEOUT_FUNCTION */
  gnutls_transport_set_push_function(http->tls, http_gnutls_write);

  while ((status = gnutls_handshake(http->tls)) != GNUTLS_E_SUCCESS)
  {
    DEBUG_printf(("5_httpStartTLS: gnutls_handshake returned %d (%s)",
                  status, gnutls_strerror(status)));

    if (gnutls_error_is_fatal(status))
    {
      http->error  = EIO;
      http->status = HTTP_STATUS_ERROR;

      _cupsSetError(IPP_STATUS_ERROR_CUPS_PKI, gnutls_strerror(status), 0);

      gnutls_deinit(http->tls);
      gnutls_certificate_free_credentials(*credentials);
      free(credentials);
      http->tls = NULL;

      return (-1);
    }
  }

  http->tls_credentials = credentials;

  return (0);
}
예제 #24
0
void SSLi_free(SSL_handle_t *session)
{
	gnutls_deinit(*session);
	free(session);
}
예제 #25
0
void
doit ()
{
  int err;
  int sockets[2];
  const char *srcdir;
  char *pub_key_path, *priv_key_path;
  pid_t child;

  gnutls_global_init ();

  srcdir = getenv ("srcdir") ? getenv ("srcdir") : ".";

  if (debug)
    {
      gnutls_global_set_log_level (10);
      gnutls_global_set_log_function (log_message);
    }

  err = socketpair (PF_UNIX, SOCK_STREAM, 0, sockets);
  if (err != 0)
    fail ("socketpair %s\n", strerror (errno));

  pub_key_path = alloca (strlen (srcdir) + strlen (pub_key_file) + 2);
  strcpy (pub_key_path, srcdir);
  strcat (pub_key_path, "/");
  strcat (pub_key_path, pub_key_file);

  priv_key_path = alloca (strlen (srcdir) + strlen (priv_key_file) + 2);
  strcpy (priv_key_path, srcdir);
  strcat (priv_key_path, "/");
  strcat (priv_key_path, priv_key_file);

  child = fork ();
  if (child == -1)
    fail ("fork %s\n", strerror (errno));

  if (child == 0)
    {
      /* Child process (client).  */
      gnutls_session_t session;
      gnutls_certificate_credentials_t cred;
      ssize_t sent;

      if (debug)
        printf ("client process %i\n", getpid ());

      err = gnutls_init (&session, GNUTLS_CLIENT);
      if (err != 0)
        fail ("client session %d\n", err);

      gnutls_priority_set_direct (session, "NONE:+VERS-TLS1.2:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+DHE-DSS:+DHE-RSA:+CTYPE-OPENPGP", NULL);
      gnutls_transport_set_ptr (session,
                                (gnutls_transport_ptr_t) (intptr_t)
                                sockets[0]);

      err = gnutls_certificate_allocate_credentials (&cred);
      if (err != 0)
        fail ("client credentials %d\n", err);

      err =
        gnutls_certificate_set_openpgp_key_file2 (cred,
                                                  pub_key_path, priv_key_path,
                                                  key_id,
                                                  GNUTLS_OPENPGP_FMT_BASE64);
      if (err != 0)
        fail ("client openpgp keys %d\n", err);

      err = gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, cred);
      if (err != 0)
        fail ("client credential_set %d\n", err);

      gnutls_dh_set_prime_bits (session, 1024);

      err = gnutls_handshake (session);
      if (err != 0)
        fail ("client handshake %s (%d) \n", gnutls_strerror(err), err);
      else if (debug)
        printf ("client handshake successful\n");

      sent = gnutls_record_send (session, message, sizeof (message));
      if (sent != sizeof (message))
        fail ("client sent %li vs. %li\n",
              (long) sent, (long) sizeof (message));

      err = gnutls_bye (session, GNUTLS_SHUT_RDWR);
      if (err != 0)
        fail ("client bye %d\n", err);

      if (debug)
        printf ("client done\n");

      gnutls_deinit(session);
      gnutls_certificate_free_credentials (cred);
    }
  else
    {
      /* Parent process (server).  */
      gnutls_session_t session;
      gnutls_dh_params_t dh_params;
      gnutls_certificate_credentials_t cred;
      char greetings[sizeof (message) * 2];
      ssize_t received;
      pid_t done;
      int status;
      const gnutls_datum_t p3 = { (char *) pkcs3, strlen (pkcs3) };

      if (debug)
        printf ("server process %i (child %i)\n", getpid (), child);

      err = gnutls_init (&session, GNUTLS_SERVER);
      if (err != 0)
        fail ("server session %d\n", err);

      gnutls_priority_set_direct (session, "NONE:+VERS-TLS1.2:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+DHE-DSS:+DHE-RSA:+CTYPE-OPENPGP", NULL);
      gnutls_transport_set_ptr (session,
                                (gnutls_transport_ptr_t) (intptr_t)
                                sockets[1]);

      err = gnutls_certificate_allocate_credentials (&cred);
      if (err != 0)
        fail ("server credentials %d\n", err);

      err =
        gnutls_certificate_set_openpgp_key_file2 (cred,
                                                  pub_key_path, priv_key_path,
                                                  key_id,
                                                  GNUTLS_OPENPGP_FMT_BASE64);
      if (err != 0)
        fail ("server openpgp keys %d\n", err);

      err = gnutls_dh_params_init (&dh_params);
      if (err)
        fail ("server DH params init %d\n", err);

      err =
        gnutls_dh_params_import_pkcs3 (dh_params, &p3, GNUTLS_X509_FMT_PEM);
      if (err)
        fail ("server DH params generate %d\n", err);

      gnutls_certificate_set_dh_params (cred, dh_params);

      err = gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, cred);
      if (err != 0)
        fail ("server credential_set %d\n", err);

      gnutls_certificate_server_set_request (session, GNUTLS_CERT_REQUIRE);

      err = gnutls_handshake (session);
      if (err != 0)
        fail ("server handshake %s (%d) \n", gnutls_strerror(err), err);

      received = gnutls_record_recv (session, greetings, sizeof (greetings));
      if (received != sizeof (message)
          || memcmp (greetings, message, sizeof (message)))
        fail ("server received %li vs. %li\n",
              (long) received, (long) sizeof (message));

      err = gnutls_bye (session, GNUTLS_SHUT_RDWR);
      if (err != 0)
        fail ("server bye %s (%d) \n", gnutls_strerror(err), err);

      if (debug)
        printf ("server done\n");

      gnutls_deinit(session);
      gnutls_certificate_free_credentials (cred);
      gnutls_dh_params_deinit (dh_params);

      done = wait (&status);
      if (done < 0)
        fail ("wait %s\n", strerror (errno));

      if (done != child)
        fail ("who's that?! %d\n", done);

      if (WIFEXITED (status))
        {
          if (WEXITSTATUS (status) != 0)
            fail ("child exited with status %d\n", WEXITSTATUS (status));
        }
      else if (WIFSIGNALED (status))
        fail ("child stopped by signal %d\n", WTERMSIG (status));
      else
        fail ("child failed: %d\n", status);
    }
}
예제 #26
0
int
main (int argc, char **argv)
{
  int err, ret;
  int sd, i;
  gnutls_session_t state;
  char buffer[MAX_BUF + 1];
  char portname[6];
  struct addrinfo hints, *res, *ptr;

  cmd_parser(argc, argv);

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

  sockets_init ();

  if (gnutls_global_init () < 0)
    {
      fprintf (stderr, "global state initialization error\n");
      exit (1);
    }

  gnutls_global_set_log_function (tls_log_func);
  gnutls_global_set_log_level (debug);

  printf ("Resolving '%s'...\n", hostname);
  /* get server name */
  memset (&hints, 0, sizeof (hints));
  hints.ai_socktype = SOCK_STREAM;
  hints.ai_flags = 0;
  snprintf (portname, sizeof (portname), "%d", port);
  if ((err = getaddrinfo (hostname, portname, &hints, &res)) != 0)
    {
      fprintf (stderr, "Cannot resolve %s: %s\n", hostname,
               gai_strerror (err));
      exit (1);
    }

  /* X509 stuff */
  if (gnutls_certificate_allocate_credentials (&xcred) < 0)
    {                           /* space for 2 certificates */
      fprintf (stderr, "memory error\n");
      exit (1);
    }

  /* SRP stuff */
#ifdef ENABLE_SRP
  if (gnutls_srp_allocate_client_credentials (&srp_cred) < 0)
    {
      fprintf (stderr, "memory error\n");
      exit (1);
    }
#endif

#ifdef ENABLE_ANON
  /* ANON stuff */
  if (gnutls_anon_allocate_client_credentials (&anon_cred) < 0)
    {
      fprintf (stderr, "memory error\n");
      exit (1);
    }
#endif

  i = 0;

  do
    {

      if (tls_tests[i].test_name == NULL)
        break;                  /* finished */

      /* if neither of SSL3 and TLSv1 are supported, exit
       */
      if (i > 6 && tls1_1_ok == 0 && tls1_ok == 0 && ssl3_ok == 0)
        {
          fprintf (stderr,
                   "\nServer does not support any of SSL 3.0, TLS 1.0 and TLS 1.1\n");
          break;
        }

      sd = -1;
      for (ptr = res; ptr != NULL; ptr = ptr->ai_next)
        {
          sd = socket (ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
          if (sd == -1)
            {
              continue;
            }

          getnameinfo (ptr->ai_addr, ptr->ai_addrlen, buffer, MAX_BUF,
                       NULL, 0, NI_NUMERICHOST);
          if (tt == 0)
            {
              printf ("Connecting to '%s:%d'...\n", buffer, port);
              tt = 1;
            }
          if ((err = connect (sd, ptr->ai_addr, ptr->ai_addrlen)) != 0)
            {
              close (sd);
              sd = -1;
              continue;
            }
          else
            break;
        }
      ERR (err, "connect");

      gnutls_init (&state, GNUTLS_CLIENT|GNUTLS_NO_EXTENSIONS);

      gnutls_transport_set_ptr (state, (gnutls_transport_ptr_t)
                                gl_fd_to_handle (sd));
      if (hostname && !isdigit(hostname[0]) && strchr(hostname, ':') == 0)
        gnutls_server_name_set (state, GNUTLS_NAME_DNS, hostname,
                                strlen (hostname));

      do
        {
          printf ("Checking %s...", tls_tests[i].test_name);
          fflush(stdout);

          ret = tls_tests[i].func (state);

          if (ret == TEST_SUCCEED)
            printf (" %s\n", tls_tests[i].suc_str);
          else if (ret == TEST_FAILED)
            printf (" %s\n", tls_tests[i].fail_str);
          else if (ret == TEST_UNSURE)
            printf (" %s\n", tls_tests[i].unsure_str);
          else if (ret == TEST_IGNORE)
            {
              printf (" N/A\n");
              i++;
            }
        }
      while (ret == TEST_IGNORE && tls_tests[i].test_name != NULL);

      gnutls_deinit (state);

      shutdown (sd, SHUT_RDWR); /* no more receptions */
      close (sd);

      i++;
    }
  while (1);

  freeaddrinfo (res);

#ifdef ENABLE_SRP
  gnutls_srp_free_client_credentials (srp_cred);
#endif
  gnutls_certificate_free_credentials (xcred);
#ifdef ENABLE_ANON
  gnutls_anon_free_client_credentials (anon_cred);
#endif
  gnutls_global_deinit ();

  return 0;
}
예제 #27
0
int
main (void)
{
  int err, listen_sd;
  int sd, ret;
  struct sockaddr_in sa_serv;
  struct sockaddr_in sa_cli;
  int client_len;
  char topbuf[512];
  gnutls_session_t session;
  char buffer[MAX_BUF + 1];
  int optval = 1;

  /* to disallow usage of the blocking /dev/random 
   */
  gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);

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

  gnutls_certificate_allocate_credentials (&x509_cred);
  gnutls_certificate_set_x509_trust_file (x509_cred, CAFILE,
					  GNUTLS_X509_FMT_PEM);

  gnutls_certificate_set_x509_crl_file (x509_cred, CRLFILE,
					GNUTLS_X509_FMT_PEM);

  gnutls_certificate_set_x509_key_file (x509_cred, CERTFILE, KEYFILE,
					GNUTLS_X509_FMT_PEM);

  gnutls_psk_allocate_server_credentials (&psk_cred);
  gnutls_psk_set_server_credentials_function (psk_cred, pskfunc);

  generate_dh_params ();

  gnutls_priority_init (&priority_cache, "NORMAL:PSK", NULL);


  gnutls_certificate_set_dh_params (x509_cred, dh_params);

  /* Socket operations
   */
  listen_sd = socket (AF_INET, SOCK_STREAM, 0);
  SOCKET_ERR (listen_sd, "socket");

  memset (&sa_serv, '\0', sizeof (sa_serv));
  sa_serv.sin_family = AF_INET;
  sa_serv.sin_addr.s_addr = INADDR_ANY;
  sa_serv.sin_port = htons (PORT);	/* Server Port number */

  setsockopt (listen_sd, SOL_SOCKET, SO_REUSEADDR, (void *) &optval,
	      sizeof (int));

  err = bind (listen_sd, (SA *) & sa_serv, sizeof (sa_serv));
  SOCKET_ERR (err, "bind");
  err = listen (listen_sd, 1024);
  SOCKET_ERR (err, "listen");

  printf ("Server ready. Listening to port '%d'.\n\n", PORT);

  client_len = sizeof (sa_cli);
  for (;;)
    {
      session = initialize_tls_session ();

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

      printf ("- 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);
	  fprintf (stderr, "*** Handshake has failed (%s)\n\n",
		   gnutls_strerror (ret));
	  continue;
	}
      printf ("- Handshake was completed\n");

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

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

	  if (ret == 0)
	    {
	      printf ("\n- Peer has closed the GnuTLS connection\n");
	      break;
	    }
	  else if (ret < 0)
	    {
	      fprintf (stderr, "\n*** Received corrupted "
		       "data(%d). Closing the connection.\n\n", ret);
	      break;
	    }
	  else if (ret > 0)
	    {
	      /* echo data back to the client
	       */
	      gnutls_record_send (session, buffer, strlen (buffer));
	    }
	}
      printf ("\n");
      /* 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_certificate_free_credentials (x509_cred);
  gnutls_psk_free_server_credentials (psk_cred);

  gnutls_priority_deinit (priority_cache);

  gnutls_global_deinit ();

  return 0;

}
예제 #28
0
/*
 * This function is called to shut down the SSL layer but keep the
 * socket open (CCC - Clear Command Channel)
 */
int Curl_gtls_shutdown(struct connectdata *conn, int sockindex)
{
  ssize_t result;
  int retval = 0;
  struct SessionHandle *data = conn->data;
  int done = 0;
  char buf[120];

  /* This has only been tested on the proftpd server, and the mod_tls code
     sends a close notify alert without waiting for a close notify alert in
     response. Thus we wait for a close notify alert from the server, but
     we do not send one. Let's hope other servers do the same... */

  if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
      gnutls_bye(conn->ssl[sockindex].session, GNUTLS_SHUT_WR);

  if(conn->ssl[sockindex].session) {
    while(!done) {
      int what = Curl_socket_ready(conn->sock[sockindex],
                                   CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
      if(what > 0) {
        /* Something to read, let's do it and hope that it is the close
           notify alert from the server */
        result = gnutls_record_recv(conn->ssl[sockindex].session,
                                    buf, sizeof(buf));
        switch(result) {
        case 0:
          /* This is the expected response. There was no data but only
             the close notify alert */
          done = 1;
          break;
        case GNUTLS_E_AGAIN:
        case GNUTLS_E_INTERRUPTED:
          infof(data, "GNUTLS_E_AGAIN || GNUTLS_E_INTERRUPTED\n");
          break;
        default:
          retval = -1;
          done = 1;
          break;
        }
      }
      else if(0 == what) {
        /* timeout */
        failf(data, "SSL shutdown timeout");
        done = 1;
        break;
      }
      else {
        /* anything that gets here is fatally bad */
        failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
        retval = -1;
        done = 1;
      }
    }
    gnutls_deinit(conn->ssl[sockindex].session);
  }
  gnutls_certificate_free_credentials(conn->ssl[sockindex].cred);

#ifdef USE_TLS_SRP
  if(data->set.ssl.authtype == CURL_TLSAUTH_SRP
     && data->set.ssl.username != NULL)
    gnutls_srp_free_client_credentials(conn->ssl[sockindex].srp_client_cred);
#endif

  conn->ssl[sockindex].cred = NULL;
  conn->ssl[sockindex].session = NULL;

  return retval;
}
예제 #29
0
void tls_free(tls_t *tls)
{
    gnutls_deinit(tls->session);
    gnutls_certificate_free_credentials(tls->cred);
    xmpp_free(tls->ctx, tls);
}
예제 #30
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");
	}
}