/** * 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; }
/** * 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; 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 */ n_the_key = 16; the_key = egg_dh_gen_secret (peer, priv, prime, n_the_key); ret = (the_key != NULL); } } 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; }