Example #1
0
int
print_info (gnutls_session_t session, const char *hostname, int insecure)
{
  const char *tmp;
  gnutls_credentials_type_t cred;
  gnutls_kx_algorithm_t kx;
  unsigned char session_id[33];
  size_t session_id_size = sizeof(session_id);

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

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

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

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

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

      print_cert_info (session, hostname, insecure);

      print_cert_vrfy (session);

    }

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

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

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

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

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

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

  if (verbose)
    {
      gnutls_datum_t cb;
      int rc;

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

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

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

  fflush (stdout);

  return 0;
}
static void client(int fd)
{
	int ret;
	char buffer[MAX_BUF + 1];
	gnutls_certificate_credentials_t clientx509cred;
	gnutls_anon_client_credentials_t anoncred;
	gnutls_session_t session;

	global_init();

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

	assert(gnutls_anon_allocate_client_credentials(&anoncred) >= 0);
	assert(gnutls_certificate_allocate_credentials(&clientx509cred) >= 0);

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

	assert(gnutls_priority_set_direct(session,
					  "NONE:+VERS-DTLS-ALL:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-ECDH:+CURVE-ALL",
					  NULL) >= 0);

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

	gnutls_transport_set_int(session, fd);
	gnutls_transport_set_push_function(session, push);
	gnutls_dtls_set_timeouts(session, 2000, 30 * 1000);

	/* 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 (debug)
		success("client: TLS version is: %s\n",
			gnutls_protocol_get_name
			(gnutls_protocol_get_version(session)));

	/* update priorities to allow cert auth */
	assert(gnutls_priority_set_direct(session,
					  "NONE:+VERS-DTLS-ALL:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ECDHE-RSA:+CURVE-ALL",
					  NULL) >= 0);

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

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

		if (ret != 0) {
			fail("client: Error: %s\n", gnutls_strerror(ret));
			exit(1);
		}
	}

	do {
		ret = gnutls_record_send(session, MSG, strlen(MSG));
	} while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED);
	gnutls_bye(session, GNUTLS_SHUT_WR);

 end:

	close(fd);

	gnutls_deinit(session);

	gnutls_certificate_free_credentials(clientx509cred);
	gnutls_anon_free_client_credentials(anoncred);

	gnutls_global_deinit();
}
static const char *
tlsg_session_version( tls_session *sess )
{
	tlsg_session *s = (tlsg_session *)sess;
	return gnutls_protocol_get_name(gnutls_protocol_get_version( s->session ));
}
Example #4
0
static void client(int fd, const char *prio)
{
	int ret;
	char buffer[MAX_BUF + 1];
	gnutls_anon_client_credentials_t anoncred;
	gnutls_certificate_credentials_t x509_cred;
	gnutls_session_t session;
	/* Need to enable anonymous KX specifically. */

	global_init();

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

	gnutls_anon_allocate_client_credentials(&anoncred);
	gnutls_certificate_allocate_credentials(&x509_cred);

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

	/* Use default priorities */
	gnutls_priority_set_direct(session, prio, NULL);

	/* put the anonymous credentials to the current session
	 */
	gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred);
	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 (debug)
		success("client: TLS version is: %s\n",
			gnutls_protocol_get_name
			(gnutls_protocol_get_version(session)));
	do {
		do {
			ret = gnutls_record_recv(session, buffer, MAX_BUF);
		} while (ret == GNUTLS_E_AGAIN
			 || ret == GNUTLS_E_INTERRUPTED);
	} while (ret > 0);

	if (ret == GNUTLS_E_PREMATURE_TERMINATION) {
		if (debug)
			success
			    ("client: Peer has closed the TLS connection\n");
		goto end;
	} else {
		fail("client: Unexpected error: %d (%s)\n", ret,
		     gnutls_strerror(ret));
		exit(1);
	}

      end:
	close(fd);

	gnutls_deinit(session);

	gnutls_anon_free_client_credentials(anoncred);
	gnutls_certificate_free_credentials(x509_cred);

	gnutls_global_deinit();
}
Example #5
0
static void server(int sd, const char *prio)
{
	gnutls_certificate_credentials_t x509_cred;
	int ret;
	gnutls_session_t session;
	char buffer[MAX_BUF + 1];

	/* this must be called once in the program
	 */
	gnutls_global_set_log_function(tls_log_func);
	if (debug)
		gnutls_global_set_log_level(6);

	gnutls_certificate_allocate_credentials(&x509_cred);
	gnutls_certificate_set_x509_trust_mem(x509_cred, &ca,
					      GNUTLS_X509_FMT_PEM);

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

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

	gnutls_init(&session, GNUTLS_SERVER);

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

	gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred);

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

	gnutls_certificate_free_credentials(x509_cred);

	if (debug)
		success("server: finished\n");
}
Example #6
0
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_certificate_allocate_credentials (&x509_cred);
  gnutls_certificate_set_x509_trust_mem (x509_cred, &ca, GNUTLS_X509_FMT_PEM);

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

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

  generate_dh_params ();

  gnutls_certificate_set_dh_params (x509_cred, 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 */
  if (debug)
    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_certificate_free_credentials (x509_cred);

  gnutls_dh_params_deinit (dh_params);

  gnutls_global_deinit ();

  if (debug)
    success ("server: finished\n");
}
Example #7
0
/* Generates a signature of all the previous sent packets in the 
 * handshake procedure. 
 * 20040227: now it works for SSL 3.0 as well
 * 20091031: works for TLS 1.2 too!
 *
 * For TLS1.x, x<2 returns negative for failure and zero or unspecified for success.
 * For TLS1.2 returns the signature algorithm used on success, or a negative value;
 */
int
_gnutls_handshake_sign_cert_vrfy (gnutls_session_t session,
                                  gnutls_pcert_st* cert, gnutls_privkey_t pkey,
                                  gnutls_datum_t * signature)
{
  gnutls_datum_t dconcat;
  int ret;
  opaque concat[MAX_SIG_SIZE];
  digest_hd_st td_md5;
  digest_hd_st td_sha;
  gnutls_protocol_t ver = gnutls_protocol_get_version (session);
  gnutls_pk_algorithm_t pk = gnutls_pubkey_get_pk_algorithm(cert->pubkey, NULL);

  if (session->security_parameters.handshake_mac_handle_type ==
      HANDSHAKE_MAC_TYPE_12)
    {
      return _gnutls_handshake_sign_cert_vrfy12 (session, cert, pkey,
                                                 signature);
    }
  else if (session->security_parameters.handshake_mac_handle_type !=
           HANDSHAKE_MAC_TYPE_10)
    {
      gnutls_assert ();
      return GNUTLS_E_INTERNAL_ERROR;
    }

  ret =
    _gnutls_hash_copy (&td_sha,
                       &session->internals.handshake_mac_handle.tls10.sha);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  if (ver == GNUTLS_SSL3)
    {
      ret = _gnutls_generate_master (session, 1);
      if (ret < 0)
        {
          gnutls_assert ();
          _gnutls_hash_deinit (&td_sha, NULL);
          return ret;
        }

      ret = _gnutls_mac_deinit_ssl3_handshake (&td_sha, &concat[16],
                                         session->
                                         security_parameters.master_secret,
                                         GNUTLS_MASTER_SIZE);
      if (ret < 0)
        return gnutls_assert_val(ret);
    }
  else
    _gnutls_hash_deinit (&td_sha, &concat[16]);

  /* ensure 1024 bit DSA keys are used */
  ret = _gnutls_pubkey_compatible_with_sig(cert->pubkey, ver, GNUTLS_SIGN_UNKNOWN);
  if (ret < 0)
    return gnutls_assert_val(ret);

  switch (pk)
    {
    case GNUTLS_PK_RSA:
      ret =
        _gnutls_hash_copy (&td_md5,
                           &session->internals.handshake_mac_handle.tls10.
                           md5);
      if (ret < 0)
        {
          gnutls_assert ();
          return ret;
        }

      if (ver == GNUTLS_SSL3)
        {
          ret = _gnutls_mac_deinit_ssl3_handshake (&td_md5, concat,
                                           session->
                                           security_parameters.master_secret,
                                           GNUTLS_MASTER_SIZE);
          if (ret < 0)
            return gnutls_assert_val(ret);
        }
      else
        _gnutls_hash_deinit (&td_md5, concat);

      dconcat.data = concat;
      dconcat.size = 36;
      break;
    case GNUTLS_PK_DSA:

      dconcat.data = &concat[16];
      dconcat.size = 20;
      break;

    default:
      return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
    }
  ret = sign_tls_hash (session, GNUTLS_DIG_NULL, cert, pkey, &dconcat, signature);
  if (ret < 0)
    {
      gnutls_assert ();
    }

  return ret;
}
static void server(int fd)
{
	int ret;
	char buffer[MAX_BUF + 1];
	gnutls_session_t session;
	gnutls_certificate_credentials_t x509_cred;

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

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

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

	gnutls_init(&session, GNUTLS_SERVER);

	/* avoid calling all the priority functions, since the defaults
	 * are adequate.
	 */
	gnutls_priority_set_direct(session, "NORMAL", 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) {
		/* 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)));

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

 end:
	close(fd);
	gnutls_deinit(session);

	gnutls_certificate_free_credentials(x509_cred);

	gnutls_global_deinit();

	if (debug)
		success("server: finished\n");
}
Example #9
0
/* Verifies a TLS signature (like the one in the client certificate
 * verify message). 
 */
int
_gnutls_handshake_verify_cert_vrfy (gnutls_session_t session,
                                    gnutls_pcert_st *cert,
                                    gnutls_datum_t * signature,
                                    gnutls_sign_algorithm_t sign_algo)
{
  int ret;
  opaque concat[MAX_SIG_SIZE];
  digest_hd_st td_md5;
  digest_hd_st td_sha;
  gnutls_datum_t dconcat;
  gnutls_protocol_t ver = gnutls_protocol_get_version (session);

  _gnutls_handshake_log ("HSK[%p]: verify cert vrfy: using %s\n",
                    session, gnutls_sign_algorithm_get_name (sign_algo));

  if (session->security_parameters.handshake_mac_handle_type ==
      HANDSHAKE_MAC_TYPE_12)
    {
      return _gnutls_handshake_verify_cert_vrfy12 (session, cert, signature,
                                                   sign_algo);
    }
  else if (session->security_parameters.handshake_mac_handle_type !=
           HANDSHAKE_MAC_TYPE_10)
    {
      gnutls_assert ();
      return GNUTLS_E_INTERNAL_ERROR;
    }

  ret =
    _gnutls_hash_copy (&td_md5,
                       &session->internals.handshake_mac_handle.tls10.md5);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  ret =
    _gnutls_hash_copy (&td_sha,
                       &session->internals.handshake_mac_handle.tls10.sha);
  if (ret < 0)
    {
      gnutls_assert ();
      _gnutls_hash_deinit (&td_md5, NULL);
      return GNUTLS_E_HASH_FAILED;
    }

  if (ver == GNUTLS_SSL3)
    {
      ret = _gnutls_generate_master (session, 1);
      if (ret < 0)
        {
          _gnutls_hash_deinit (&td_md5, NULL);
          _gnutls_hash_deinit (&td_sha, NULL);
          return gnutls_assert_val(ret);
        }

      ret = _gnutls_mac_deinit_ssl3_handshake (&td_md5, concat,
                                         session->
                                         security_parameters.master_secret,
                                         GNUTLS_MASTER_SIZE);
      if (ret < 0)
        {
          _gnutls_hash_deinit (&td_sha, NULL);
          return gnutls_assert_val(ret);
        }

      ret = _gnutls_mac_deinit_ssl3_handshake (&td_sha, &concat[16],
                                         session->
                                         security_parameters.master_secret,
                                         GNUTLS_MASTER_SIZE);
      if (ret < 0)
        {
          return gnutls_assert_val(ret);
        }
    }
  else
    {
      _gnutls_hash_deinit (&td_md5, concat);
      _gnutls_hash_deinit (&td_sha, &concat[16]);
    }

  dconcat.data = concat;
  dconcat.size = 20 + 16;       /* md5+ sha */

  ret =
    verify_tls_hash (ver, cert, &dconcat, signature, 16,
                        gnutls_pubkey_get_pk_algorithm(cert->pubkey, NULL));
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  return ret;

}
Example #10
0
/* Generates a signature of all the random data and the parameters.
 * Used in DHE_* ciphersuites.
 */
int
_gnutls_handshake_sign_data (gnutls_session_t session, gnutls_pcert_st* cert,
                             gnutls_privkey_t pkey, gnutls_datum_t * params,
                             gnutls_datum_t * signature,
                             gnutls_sign_algorithm_t * sign_algo)
{
  gnutls_datum_t dconcat;
  int ret;
  digest_hd_st td_sha;
  opaque concat[MAX_SIG_SIZE];
  gnutls_protocol_t ver = gnutls_protocol_get_version (session);
  gnutls_digest_algorithm_t hash_algo;

  *sign_algo =
    _gnutls_session_get_sign_algo (session, cert);
  if (*sign_algo == GNUTLS_SIGN_UNKNOWN)
    {
      gnutls_assert ();
      return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
    }

  hash_algo = _gnutls_sign_get_hash_algorithm (*sign_algo);

  _gnutls_handshake_log ("HSK[%p]: signing handshake data: using %s\n",
                    session, gnutls_sign_algorithm_get_name (*sign_algo));

  ret = _gnutls_hash_init (&td_sha, hash_algo);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  _gnutls_hash (&td_sha, session->security_parameters.client_random,
                GNUTLS_RANDOM_SIZE);
  _gnutls_hash (&td_sha, session->security_parameters.server_random,
                GNUTLS_RANDOM_SIZE);
  _gnutls_hash (&td_sha, params->data, params->size);

  switch (gnutls_pubkey_get_pk_algorithm(cert->pubkey, NULL))
    {
    case GNUTLS_PK_RSA:
      if (!_gnutls_version_has_selectable_sighash (ver))
        {
          digest_hd_st td_md5;

          ret = _gnutls_hash_init (&td_md5, GNUTLS_MAC_MD5);
          if (ret < 0)
            {
              gnutls_assert ();
              return ret;
            }

          _gnutls_hash (&td_md5, session->security_parameters.client_random,
                        GNUTLS_RANDOM_SIZE);
          _gnutls_hash (&td_md5, session->security_parameters.server_random,
                        GNUTLS_RANDOM_SIZE);
          _gnutls_hash (&td_md5, params->data, params->size);

          _gnutls_hash_deinit (&td_md5, concat);
          _gnutls_hash_deinit (&td_sha, &concat[16]);

          dconcat.data = concat;
          dconcat.size = 36;
        }
      else
        { /* TLS 1.2 way */

          _gnutls_hash_deinit (&td_sha, concat);

          dconcat.data = concat;
          dconcat.size = _gnutls_hash_get_algo_len (hash_algo);
        }
      break;
    case GNUTLS_PK_DSA:
      _gnutls_hash_deinit (&td_sha, concat);

      if ((hash_algo != GNUTLS_DIG_SHA1) && (hash_algo != GNUTLS_DIG_SHA224)
          && (hash_algo != GNUTLS_DIG_SHA256))
        {
          gnutls_assert ();
          return GNUTLS_E_INTERNAL_ERROR;
        }
      dconcat.data = concat;
      dconcat.size = _gnutls_hash_get_algo_len (hash_algo);
      break;

    default:
      gnutls_assert ();
      _gnutls_hash_deinit (&td_sha, NULL);
      return GNUTLS_E_INTERNAL_ERROR;
    }

  ret = sign_tls_hash (session, hash_algo, cert, pkey, &dconcat, signature);
  if (ret < 0)
    {
      gnutls_assert ();
    }

  return ret;

}
Example #11
0
/* Generates a signature of all the random data and the parameters.
 * Used in DHE_* ciphersuites.
 */
int
_gnutls_handshake_verify_data (gnutls_session_t session, gnutls_pcert_st* cert,
                               const gnutls_datum_t * params,
                               gnutls_datum_t * signature,
                               gnutls_sign_algorithm_t algo)
{
  gnutls_datum_t dconcat;
  int ret;
  digest_hd_st td_md5;
  digest_hd_st td_sha;
  opaque concat[MAX_SIG_SIZE];
  gnutls_protocol_t ver = gnutls_protocol_get_version (session);
  gnutls_digest_algorithm_t hash_algo;

  if (_gnutls_version_has_selectable_sighash (ver))
    {
      _gnutls_handshake_log ("HSK[%p]: verify handshake data: using %s\n",
                    session, gnutls_sign_algorithm_get_name (algo));

      ret = _gnutls_pubkey_compatible_with_sig(cert->pubkey, ver, algo);
      if (ret < 0)
        return gnutls_assert_val(ret);

      ret = _gnutls_session_sign_algo_enabled (session, algo);
      if (ret < 0)
        return gnutls_assert_val(ret);

      hash_algo = _gnutls_sign_get_hash_algorithm (algo);
    }
  else
    {
      ret = _gnutls_hash_init (&td_md5, GNUTLS_MAC_MD5);
      if (ret < 0)
        {
          gnutls_assert ();
          return ret;
        }

      _gnutls_hash (&td_md5, session->security_parameters.client_random,
                    GNUTLS_RANDOM_SIZE);
      _gnutls_hash (&td_md5, session->security_parameters.server_random,
                    GNUTLS_RANDOM_SIZE);
      _gnutls_hash (&td_md5, params->data, params->size);

      hash_algo = GNUTLS_DIG_SHA1;
    }

  ret = _gnutls_hash_init (&td_sha, hash_algo);
  if (ret < 0)
    {
      gnutls_assert ();
      if (!_gnutls_version_has_selectable_sighash (ver))
        _gnutls_hash_deinit (&td_md5, NULL);
      return ret;
    }

  _gnutls_hash (&td_sha, session->security_parameters.client_random,
                GNUTLS_RANDOM_SIZE);
  _gnutls_hash (&td_sha, session->security_parameters.server_random,
                GNUTLS_RANDOM_SIZE);
  _gnutls_hash (&td_sha, params->data, params->size);

  if (!_gnutls_version_has_selectable_sighash (ver))
    {
      _gnutls_hash_deinit (&td_md5, concat);
      _gnutls_hash_deinit (&td_sha, &concat[16]);
      dconcat.data = concat;
      dconcat.size = 36;
    }
  else
    {
      _gnutls_hash_deinit (&td_sha, concat);

      dconcat.data = concat;
      dconcat.size = _gnutls_hash_get_algo_len (hash_algo);
    }

  ret = verify_tls_hash (ver, cert, &dconcat, signature,
                            dconcat.size -
                            _gnutls_hash_get_algo_len (hash_algo),
                            _gnutls_sign_get_pk_algorithm (algo));
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  return ret;

}
static void
client (int fd, int server_init)
{
  int ret;
  char buffer[MAX_BUF + 1];
  gnutls_anon_client_credentials_t anoncred;
  /* Need to enable anonymous KX specifically. */

  global_init ();

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

  gnutls_anon_allocate_client_credentials (&anoncred);

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

  /* Use default priorities */
  gnutls_priority_set_direct (session, "NONE:+VERS-DTLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-ECDH:+CURVE-ALL", NULL);

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

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

  /* 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 (debug)
    success ("client: TLS version is: %s\n",
             gnutls_protocol_get_name (gnutls_protocol_get_version
                                       (session)));

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

      if (ret < 0)
        {
          fail ("2nd client gnutls_handshake: %s\n", gnutls_strerror(ret));
          terminate();
        }
    }
  else
    {
      do {
        ret = gnutls_record_recv (session, buffer, MAX_BUF);
      } while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED);
    }

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

      if (ret != 0)
        {
          fail ("client: Error: %s\n", gnutls_strerror (ret));
          exit(1);
        }
    }

  do {
    ret = gnutls_record_send (session, MSG, strlen (MSG));
  } while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED);
  gnutls_bye (session, GNUTLS_SHUT_WR);

end:

  close (fd);

  gnutls_deinit (session);

  gnutls_anon_free_client_credentials (anoncred);

  gnutls_global_deinit ();
}
static void
server (int fd, int server_init)
{
int ret;
char buffer[MAX_BUF + 1];
  /* this must be called once in the program
   */
  global_init ();

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

  gnutls_anon_allocate_server_credentials (&anoncred);

  session = initialize_tls_session ();

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

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

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

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

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

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

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

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

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

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

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

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

  close (fd);
  gnutls_deinit (session);

  gnutls_anon_free_server_credentials (anoncred);

  gnutls_global_deinit ();

  if (debug)
    success ("server: finished\n");
}
static void server(int fd)
{
	int ret;
	char buffer[MAX_BUF + 1];
	gnutls_certificate_credentials_t serverx509cred;
	gnutls_anon_server_credentials_t anoncred;
	gnutls_session_t session;
	/* this must be called once in the program
	 */
	global_init();

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	close(fd);
	gnutls_deinit(session);

	gnutls_certificate_free_credentials(serverx509cred);
	gnutls_anon_free_server_credentials(anoncred);

	gnutls_global_deinit();

	if (debug)
		success("server: finished\n");
}
Example #15
0
static void start(struct test_st *test)
{
	int ret;
	/* Server stuff. */
	gnutls_priority_t cache;
	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;
	const char *ep;
	int cret = GNUTLS_E_AGAIN;

	if (test == NULL)
		success("running gnutls_set_default_priority test\n");
	else
		success("running %s\n", test->name);

	if (test && test->def_prio)
		_gnutls_default_priority_string = test->def_prio;
	else
		_gnutls_default_priority_string = "NORMAL";

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

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

	assert(gnutls_init(&server, GNUTLS_SERVER) >= 0);
	gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE,
				serverx509cred);
	if (test == NULL) {
		ret = gnutls_priority_init(&cache, NULL, NULL);
		if (ret < 0)
			fail("error: %s\n", gnutls_strerror(ret));
	} else {
		ret = gnutls_priority_init2(&cache, test->add_prio, &ep, GNUTLS_PRIORITY_INIT_DEF_APPEND);
		if (ret < 0) {
			if (test->exp_err == ret) {
				if (strchr(_gnutls_default_priority_string, '@') != 0) {
					if (ep != test->add_prio) {
						fail("error expected error on start of string[%d]: %s\n",
							test->err_pos, test->add_prio);
					}
				} else {
					if (ep-test->add_prio != test->err_pos) {
						fprintf(stderr, "diff: %d\n", (int)(ep-test->add_prio));
						fail("error expected error on different position[%d]: %s\n",
							test->err_pos, test->add_prio);
					}
				}
				goto cleanup;
			}
			fail("error: %s\n", gnutls_strerror(ret));
		}
	}
	gnutls_priority_set(server, cache);

	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);
	if (ret < 0)
		exit(1);

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

	ret = gnutls_set_default_priority(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);

	HANDSHAKE(client, server);

	/* check gnutls_certificate_get_ours() - client side */
	{
		const gnutls_datum_t *mcert;

		mcert = gnutls_certificate_get_ours(client);
		if (mcert != NULL) {
			fail("gnutls_certificate_get_ours(): failed\n");
			exit(1);
		}
	}

	if (test && test->exp_vers != 0) {
		if (test->exp_vers != gnutls_protocol_get_version(server)) {
			fail("expected version %s, got %s\n",
			     gnutls_protocol_get_name(test->exp_vers),
			     gnutls_protocol_get_name(gnutls_protocol_get_version(server)));
		}
	}

	/* check the number of certificates received */
	{
		unsigned cert_list_size = 0;
		gnutls_typed_vdata_st data[2];
		unsigned status;

		memset(data, 0, sizeof(data));

		data[0].type = GNUTLS_DT_DNS_HOSTNAME;
		data[0].data = (void*)"localhost1";

		data[1].type = GNUTLS_DT_KEY_PURPOSE_OID;
		data[1].data = (void*)GNUTLS_KP_TLS_WWW_SERVER;

		gnutls_certificate_get_peers(client, &cert_list_size);
		if (cert_list_size < 2) {
			fprintf(stderr, "received a certificate list of %d!\n", cert_list_size);
			exit(1);
		}

		ret = gnutls_certificate_verify_peers(client, data, 2, &status);
		if (ret < 0) {
			fprintf(stderr, "could not verify certificate: %s\n", gnutls_strerror(ret));
			exit(1);
		}

		if (status == 0) {
			fprintf(stderr, "should not have accepted!\n");
			exit(1);
		}

		data[0].type = GNUTLS_DT_DNS_HOSTNAME;
		data[0].data = (void*)"localhost";

		ret = gnutls_certificate_verify_peers(client, data, 2, &status);
		if (ret < 0) {
			fprintf(stderr, "could not verify certificate: %s\n", gnutls_strerror(ret));
			exit(1);
		}

		if (status != 0) {
			fprintf(stderr, "could not verify certificate: %.4x\n", status);
			exit(1);
		}
	}

	if (test && test->exp_etm) {
		ret = gnutls_session_ext_master_secret_status(client);
		if (ret != 1) {
			fprintf(stderr, "Extended master secret wasn't negotiated by default (client ret: %d)\n", ret);
			exit(1);
		}

		ret = gnutls_session_ext_master_secret_status(server);
		if (ret != 1) {
			fprintf(stderr, "Extended master secret wasn't negotiated by default (server ret: %d)\n", ret);
			exit(1);
		}
	}

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

	gnutls_deinit(client);
	gnutls_certificate_free_credentials(clientx509cred);
 cleanup:
	gnutls_priority_deinit(cache);
	gnutls_deinit(server);

	gnutls_certificate_free_credentials(serverx509cred);

	gnutls_global_deinit();
	reset_buffers();
}
Example #16
0
static void client(int fd)
{
	int ret;
	unsigned int status;
	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);

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

	gnutls_handshake_set_hook_function(session, GNUTLS_HANDSHAKE_CERTIFICATE_STATUS,
					   GNUTLS_HOOK_POST,
					   handshake_callback);

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

	if (received == 1) {
		fail("client: received certificate status when we shouldn't.\n");
		terminate();
	}

	ret = gnutls_certificate_verify_peers2(session, &status);
	if (ret != GNUTLS_E_SUCCESS) {
		fail("client: Peer certificate validation failed: %s\n", gnutls_strerror(ret));
		terminate();
	}
	else {
		if (status & GNUTLS_CERT_MISSING_OCSP_STATUS) {
			success("client: Validation failed with GNUTLS_CERT_MISSING_OCSP_STATUS\n");
		}
		else {
			fail("client: Validation status does not include GNUTLS_CERT_MISSING_OCSP_STATUS. Status is %d\n", status);
			terminate();
		}
	}

	gnutls_bye(session, GNUTLS_SHUT_WR);

      end:

	close(fd);

	gnutls_deinit(session);

	gnutls_certificate_free_credentials(x509_cred);

	gnutls_global_deinit();
}
Example #17
0
static void
client (void)
{
  int ret, sd, ii;
  gnutls_session_t session;
  char buffer[MAX_BUF + 1];
  gnutls_certificate_credentials_t xcred;

  gnutls_global_init ();

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

  gnutls_certificate_allocate_credentials (&xcred);

  /* sets the trusted cas file
   */
  gnutls_certificate_set_x509_trust_mem (xcred, &ca, GNUTLS_X509_FMT_PEM);

  gnutls_certificate_client_set_retrieve_function (xcred, cert_callback);

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

  /* Use default priorities */
  gnutls_set_default_priority (session);

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

  /* 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)
    {
      fail ("client: Handshake failed\n");
      gnutls_perror (ret);
      goto end;
    }
  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)));

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

end:

  tcp_close (sd);

  gnutls_deinit (session);

  gnutls_certificate_free_credentials (xcred);

  gnutls_global_deinit ();
}
Example #18
0
/* Generates a signature of all the random data and the parameters.
 * Used in DHE_* ciphersuites.
 */
int
_gnutls_tls_sign_params (gnutls_session_t session, gnutls_cert * cert,
			 gnutls_privkey * pkey, gnutls_datum_t * params,
			 gnutls_datum_t * signature)
{
  gnutls_datum_t dconcat;
  int ret;
  digest_hd_st td_sha;
  opaque concat[36];
  gnutls_protocol_t ver = gnutls_protocol_get_version (session);

  ret = _gnutls_hash_init (&td_sha, GNUTLS_MAC_SHA1);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  _gnutls_hash (&td_sha, session->security_parameters.client_random,
		GNUTLS_RANDOM_SIZE);
  _gnutls_hash (&td_sha, session->security_parameters.server_random,
		GNUTLS_RANDOM_SIZE);
  _gnutls_hash (&td_sha, params->data, params->size);

  switch (cert->subject_pk_algorithm)
    {
    case GNUTLS_PK_RSA:
      if (ver < GNUTLS_TLS1_2)
	{
	  digest_hd_st td_md5;

	  ret = _gnutls_hash_init (&td_md5, GNUTLS_MAC_MD5);
	  if (ret < 0)
	    {
	      gnutls_assert ();
	      return ret;
	    }

	  _gnutls_hash (&td_md5, session->security_parameters.client_random,
			GNUTLS_RANDOM_SIZE);
	  _gnutls_hash (&td_md5, session->security_parameters.server_random,
			GNUTLS_RANDOM_SIZE);
	  _gnutls_hash (&td_md5, params->data, params->size);

	  _gnutls_hash_deinit (&td_md5, concat);
	  _gnutls_hash_deinit (&td_sha, &concat[16]);

	  dconcat.size = 36;
	}
      else
	{
#if 1
	  /* Use NULL parameters. */
	  memcpy (concat,
		  "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14",
		  15);
	  _gnutls_hash_deinit (&td_sha, &concat[15]);
	  dconcat.size = 35;
#else
	  /* No parameters field. */
	  memcpy (concat,
		  "\x30\x1f\x30\x07\x06\x05\x2b\x0e\x03\x02\x1a\x04\x14", 13);
	  _gnutls_hash_deinit (&td_sha, &concat[13]);
	  dconcat.size = 33;
#endif
	}
      dconcat.data = concat;
      break;
    case GNUTLS_PK_DSA:
      _gnutls_hash_deinit (&td_sha, concat);
      dconcat.data = concat;
      dconcat.size = 20;
      break;

    default:
      gnutls_assert ();
      _gnutls_hash_deinit (&td_sha, NULL);
      return GNUTLS_E_INTERNAL_ERROR;
    }
  ret = _gnutls_tls_sign (session, cert, pkey, &dconcat, signature);
  if (ret < 0)
    {
      gnutls_assert ();
    }

  return ret;

}
Example #19
0
static void client(int sd, const char *prio)
{
	int ret, ii;
	gnutls_session_t session;
	char buffer[MAX_BUF + 1];
	gnutls_certificate_credentials_t xcred;

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

	gnutls_certificate_allocate_credentials(&xcred);

	/* sets the trusted cas file
	 */
	gnutls_certificate_set_x509_trust_mem(xcred, &ca,
					      GNUTLS_X509_FMT_PEM);
	gnutls_certificate_set_x509_key_mem(xcred, &cert, &key,
					    GNUTLS_X509_FMT_PEM);

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

	assert(gnutls_priority_set_direct(session, prio, NULL)>=0);

	/* 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 failed\n");
		gnutls_perror(ret);
		goto end;
	} 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)));

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

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

	if (ret == strlen(MSG)) {
		if (debug)
			success("client: sent record.\n");
	} else {
		fail("client: failed to send record.\n");
		gnutls_perror(ret);
		goto end;
	}

	ret = gnutls_record_recv(session, buffer, MAX_BUF);

	if (debug)
		success("client: recv returned %d.\n", ret);

	if (ret == GNUTLS_E_REHANDSHAKE) {
		if (debug)
			success("client: doing handshake!\n");
		ret = gnutls_handshake(session);
		if (ret == 0) {
			if (debug)
				success
				    ("client: handshake complete, reading again.\n");
			ret = gnutls_record_recv(session, buffer, MAX_BUF);
		} else {
			fail("client: handshake failed.\n");
		}
	}

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

      end:

	close(sd);

	gnutls_deinit(session);

	gnutls_certificate_free_credentials(xcred);
}