Example #1
0
static gboolean
gcr_secret_exchange_default_derive_transport_key (GcrSecretExchange *exchange,
                                                  const guchar *peer,
                                                  gsize n_peer)
{
	GcrSecretExchangeDefault *data = exchange->pv->default_exchange;
	gpointer ikm;
	gsize n_ikm;
	gcry_mpi_t mpi;

	g_return_val_if_fail (data != NULL, FALSE);
	g_return_val_if_fail (data->priv != NULL, FALSE);

	mpi = mpi_from_data (peer, n_peer);
	if (mpi == NULL)
		return FALSE;

	/* Build up a key we can use */
	ikm = egg_dh_gen_secret (mpi, data->priv, data->prime, &n_ikm);
	g_return_val_if_fail (ikm != NULL, FALSE);

	if (data->key == NULL)
		data->key = egg_secure_alloc (EXCHANGE_1_KEY_LENGTH);

	if (!egg_hkdf_perform (EXCHANGE_1_HASH_ALGO, ikm, n_ikm, NULL, 0,
	                       NULL, 0, data->key, EXCHANGE_1_KEY_LENGTH))
		g_return_val_if_reached (FALSE);

	egg_secure_free (ikm);
	gcry_mpi_release (mpi);

	return TRUE;
}
Example #2
0
/**
* Negotiates crypto between the calling programm and the prompt
*
* Reads data from the transport section of input_data and sends the public key back
* in the transport section of the output_data.
*
* Returns TRUE on success
**/
static gboolean
negotiate_transport_crypto (void)
{
	gcry_mpi_t base, prime, peer;
	gcry_mpi_t key, pub, priv;
	gboolean ret = FALSE;
	gpointer ikm;
	gsize n_ikm;

	g_assert (!the_key);
	base = prime = peer = NULL;
	key = pub = priv = NULL;

	/* The DH stuff coming in from our caller */
	if (gku_prompt_util_decode_mpi (input_data, "transport", "prime", &prime) &&
	    gku_prompt_util_decode_mpi (input_data, "transport", "base", &base) &&
	    gku_prompt_util_decode_mpi (input_data, "transport", "public", &peer)) {

		/* Generate our own public/priv, and then a key, send it back */
		if (egg_dh_gen_pair (prime, base, 0, &pub, &priv)) {

			gku_prompt_util_encode_mpi (output_data, "transport", "public", pub);

			/* Build up a key we can use */
			ikm = egg_dh_gen_secret (peer, priv, prime, &n_ikm);
			if (ikm != NULL) {
				n_the_key = 16;
				the_key = egg_secure_alloc (n_the_key);
				if (!egg_hkdf_perform ("sha256", ikm, n_ikm, NULL, 0, NULL, 0, the_key, n_the_key))
					g_return_val_if_reached (FALSE);
				ret = TRUE;
			}
		}
	}

	gcry_mpi_release (base);
	gcry_mpi_release (prime);
	gcry_mpi_release (peer);
	gcry_mpi_release (key);
	gcry_mpi_release (pub);
	gcry_mpi_release (priv);

	return ret;
}
Example #3
0
static gboolean
response_open_session_aes (SecretSession *session,
                           GVariant *response)
{
	gconstpointer buffer;
	GVariant *argument;
	const gchar *sig;
	gsize n_buffer;
	gcry_mpi_t peer;
	gcry_error_t gcry;
	gpointer ikm;
	gsize n_ikm;

	sig = g_variant_get_type_string (response);
	g_return_val_if_fail (sig != NULL, FALSE);

	if (!g_str_equal (sig, "(vo)")) {
		g_warning ("invalid OpenSession() response from daemon with signature: %s", sig);
		return FALSE;
	}

	g_assert (session->path == NULL);
	g_variant_get (response, "(vo)", &argument, &session->path);

	buffer = g_variant_get_fixed_array (argument, &n_buffer, sizeof (guchar));
	gcry = gcry_mpi_scan (&peer, GCRYMPI_FMT_USG, buffer, n_buffer, NULL);
	g_return_val_if_fail (gcry == 0, FALSE);
	g_variant_unref (argument);

#if 0
	g_printerr (" lib publi: ");
	gcry_mpi_dump (session->publi);
	g_printerr ("\n  lib peer: ");
	gcry_mpi_dump (peer);
	g_printerr ("\n");
#endif

	ikm = egg_dh_gen_secret (peer, session->privat, session->prime, &n_ikm);
	gcry_mpi_release (peer);

#if 0
	g_printerr ("   lib ikm:  %s\n", egg_hex_encode (ikm, n_ikm));
#endif

	if (ikm == NULL) {
		g_warning ("couldn't negotiate a valid AES session key");
		g_free (session->path);
		session->path = NULL;
		return FALSE;
	}

	session->n_key = 16;
	session->key = egg_secure_alloc (session->n_key);
	if (!egg_hkdf_perform ("sha256", ikm, n_ikm, NULL, 0, NULL, 0,
	                       session->key, session->n_key))
		g_return_val_if_reached (FALSE);
	egg_secure_free (ikm);

	session->algorithms = ALGORITHMS_AES;
	return TRUE;
}