summaryrefslogtreecommitdiff
path: root/egg/egg-dh.c
diff options
context:
space:
mode:
authorStef Walter <stef@memberwebs.com>2009-12-12 00:02:04 +0000
committerStef Walter <stef@memberwebs.com>2009-12-12 00:02:04 +0000
commit7475c3447d99ac271966f6bc80ad36bfcb234474 (patch)
tree1418930fbaa660215124201d6c1abdafde69fb70 /egg/egg-dh.c
parentd04b105217b1fb5a0a135171abfaa30e6416bbdf (diff)
downloadgcr-7475c3447d99ac271966f6bc80ad36bfcb234474.tar.gz
Simplify creation of secret from DH negotiation.
PKCS#11 says to use the low order bytes, and that's what we do here. This bears more research to make sure we're doing this in a standard way.
Diffstat (limited to 'egg/egg-dh.c')
-rw-r--r--egg/egg-dh.c150
1 files changed, 59 insertions, 91 deletions
diff --git a/egg/egg-dh.c b/egg/egg-dh.c
index d90abc0..f162f4d 100644
--- a/egg/egg-dh.c
+++ b/egg/egg-dh.c
@@ -21,9 +21,10 @@
#include "config.h"
-#include "egg-asn1.h"
#include "egg-dh.h"
-#include "egg-openssl.h"
+#include "egg-secure-memory.h"
+
+#define DEBUG_DH_SECRET 0
typedef struct _DHGroup {
const gchar *name;
@@ -238,16 +239,18 @@ egg_dh_default_params (const gchar *name, gcry_mpi_t *prime, gcry_mpi_t *base)
gcry_error_t gcry;
g_return_val_if_fail (name, FALSE);
- g_return_val_if_fail (prime, FALSE);
- g_return_val_if_fail (base, FALSE);
for (group = dh_groups; group->name; ++group) {
if (g_str_equal (group->name, name)) {
- gcry = gcry_mpi_scan (prime, GCRYMPI_FMT_USG, group->prime, group->n_prime, NULL);
- g_return_val_if_fail (gcry == 0, FALSE);
- g_return_val_if_fail (gcry_mpi_get_nbits (*prime) == group->bits, FALSE);
- gcry = gcry_mpi_scan (base, GCRYMPI_FMT_USG, group->base, group->n_base, NULL);
- g_return_val_if_fail (gcry == 0, FALSE);
+ if (prime) {
+ gcry = gcry_mpi_scan (prime, GCRYMPI_FMT_USG, group->prime, group->n_prime, NULL);
+ g_return_val_if_fail (gcry == 0, FALSE);
+ g_return_val_if_fail (gcry_mpi_get_nbits (*prime) == group->bits, FALSE);
+ }
+ if (base) {
+ gcry = gcry_mpi_scan (base, GCRYMPI_FMT_USG, group->base, group->n_base, NULL);
+ g_return_val_if_fail (gcry == 0, FALSE);
+ }
return TRUE;
}
}
@@ -300,91 +303,56 @@ egg_dh_gen_pair (gcry_mpi_t p, gcry_mpi_t g, guint bits,
return TRUE;
}
-gboolean
-egg_dh_gen_secret (gcry_mpi_t Y, gcry_mpi_t x,
- gcry_mpi_t p, gcry_mpi_t *k)
-{
- gint bits;
-
- g_return_val_if_fail (Y, FALSE);
- g_return_val_if_fail (x, FALSE);
- g_return_val_if_fail (p, FALSE);
- g_return_val_if_fail (k, FALSE);
-
- bits = gcry_mpi_get_nbits (p);
- g_return_val_if_fail (bits >= 0, FALSE);
-
- *k = gcry_mpi_snew (bits);
- g_return_val_if_fail (*k, FALSE);
- gcry_mpi_powm (*k, Y, x, p);
-
- return TRUE;
-}
-
-typedef struct _Parameters {
- gcry_mpi_t p;
- gcry_mpi_t g;
-} Parameters;
-
-#ifndef EGG_DH_NO_ASN1
-
-static gboolean
-parse_der_pkcs3 (const guchar *data, gsize n_data, Parameters *params)
+gpointer
+egg_dh_gen_secret (gcry_mpi_t peer, gcry_mpi_t priv,
+ gcry_mpi_t prime, gsize bytes)
{
- ASN1_TYPE asn;
- guchar *buf_p, *buf_g;
- gsize n_buf_p, n_buf_g;
gcry_error_t gcry;
+ guchar *value;
+ gsize n_value;
+ gsize offset = 0;
+ gcry_mpi_t k;
+ gint bits;
- asn = egg_asn1_decode ("PK.DHParameter", data, n_data);
- if (!asn)
- return FALSE;
-
- buf_p = egg_asn1_read_value (asn, "prime", &n_buf_p, (EggAllocator)g_realloc);
- buf_g = egg_asn1_read_value (asn, "base", &n_buf_g, (EggAllocator)g_realloc);
- g_return_val_if_fail (buf_p && buf_g, FALSE);
- gcry = gcry_mpi_scan (&params->p, GCRYMPI_FMT_STD, buf_p, n_buf_p, &n_buf_p);
- g_return_val_if_fail (gcry == 0, FALSE);
- gcry = gcry_mpi_scan (&params->g, GCRYMPI_FMT_STD, buf_g, n_buf_g, &n_buf_g);
- g_return_val_if_fail (gcry == 0, FALSE);
-
- g_free (buf_p);
- g_free (buf_g);
- return TRUE;
-}
-
-static void
-parse_openssl_pkcs3 (GQuark type, const guchar *data, gsize n_data,
- GHashTable *headers, gpointer user_data)
-{
- Parameters *params = user_data;
-
- /* Only parse the first one */
- if (params->p != NULL)
- return;
-
- if (g_quark_try_string ("DH PARAMETERS") == type)
- parse_der_pkcs3 (data, n_data, params);
-}
-
-gboolean
-egg_dh_parse_pkcs3 (const guchar *data, gsize n_data, gcry_mpi_t *p, gcry_mpi_t *g)
-{
- Parameters params;
-
- g_return_val_if_fail (data, FALSE);
- g_return_val_if_fail (p, FALSE);
- g_return_val_if_fail (g, FALSE);
+ g_return_val_if_fail (peer, NULL);
+ g_return_val_if_fail (priv, NULL);
+ g_return_val_if_fail (prime, NULL);
+
+ bits = gcry_mpi_get_nbits (prime);
+ g_return_val_if_fail (bits >= 0, NULL);
+
+ k = gcry_mpi_snew (bits);
+ g_return_val_if_fail (k, NULL);
+ gcry_mpi_powm (k, peer, priv, prime);
+
+ /* Write out the secret */
+ gcry = gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &n_value, k);
+ g_return_val_if_fail (gcry == 0, NULL);
+ if (n_value < bytes)
+ offset = bytes - n_value;
+ value = egg_secure_alloc (n_value + offset);
+ memset (value, 0, n_value + offset);
+ gcry = gcry_mpi_print (GCRYMPI_FMT_USG, value + offset, n_value, &n_value, k);
+ g_return_val_if_fail (gcry == 0, NULL);
+
+#if DEBUG_DH_SECRET
+ g_printerr ("DH SECRET: ");
+ gcry_mpi_dump (k);
+ gcry_mpi_release (k);
+#endif
+
+ if (bytes != 0 && bytes < n_value) {
+ offset = n_value - bytes;
+ memmove (value, value + offset, bytes);
+ egg_secure_clear (value + bytes, offset);
+ }
- memset (&params, 0, sizeof (params));
- if (!parse_der_pkcs3 (data, n_data, &params))
- egg_openssl_pem_parse (data, n_data, parse_openssl_pkcs3, &params);
+#if DEBUG_DH_SECRET
+ gcry_mpi_scan (&k, GCRYMPI_FMT_USG, value, bytes, NULL);
+ g_printerr ("RAW SECRET: ");
+ gcry_mpi_dump (k);
+ gcry_mpi_release (k);
+#endif
- if (!params.p || !params.g)
- return FALSE;
- *p = params.p;
- *g = params.g;
- return TRUE;
+ return value;
}
-
-#endif /* EGG_DH_NO_ASN1 */