[gnome-keyring/dbus-api: 3/5] [egg] Add DH functions for use by IPC.
- From: Stefan Walter <stefw src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnome-keyring/dbus-api: 3/5] [egg] Add DH functions for use by IPC.
- Date: Sat, 10 Oct 2009 15:06:07 +0000 (UTC)
commit e5435bab28b5b2bb12ad3d3fbcfebb3c59a1f482
Author: Stef Walter <stef memberwebs com>
Date: Sun Oct 4 18:18:31 2009 +0000
[egg] Add DH functions for use by IPC.
egg/Makefile.am | 1 +
egg/egg-dh.c | 144 +++++++++++++++++++++++++++++++++++++
egg/egg-dh.h | 35 +++++++++
egg/tests/Makefile.am | 1 +
egg/tests/test-data/dh-params.pem | 5 ++
egg/tests/unit-test-dh.c | 89 +++++++++++++++++++++++
6 files changed, 275 insertions(+), 0 deletions(-)
---
diff --git a/egg/Makefile.am b/egg/Makefile.am
index 7aa281e..b42bc5f 100644
--- a/egg/Makefile.am
+++ b/egg/Makefile.am
@@ -22,6 +22,7 @@ libegg_la_SOURCES = \
egg-asn1.c egg-asn1.h \
egg-buffer.c egg-buffer.h \
egg-cleanup.c egg-cleanup.h \
+ egg-dh.c egg-dh.h \
egg-hex.c egg-hex.h \
egg-libgcrypt.c egg-libgcrypt.h \
egg-oid.c egg-oid.h \
diff --git a/egg/egg-dh.c b/egg/egg-dh.c
new file mode 100644
index 0000000..bc14f36
--- /dev/null
+++ b/egg/egg-dh.c
@@ -0,0 +1,144 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2009 Stefan Walter
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "egg-asn1.h"
+#include "egg-dh.h"
+#include "egg-openssl.h"
+
+gboolean
+egg_dh_gen_secret (gcry_mpi_t p, gcry_mpi_t g,
+ gcry_mpi_t *X, gcry_mpi_t *x)
+{
+ gint bits;
+
+ g_return_val_if_fail (g, FALSE);
+ g_return_val_if_fail (p, FALSE);
+ g_return_val_if_fail (X, FALSE);
+ g_return_val_if_fail (x, FALSE);
+
+ /* Secret key value must be less than half of p */
+ bits = gcry_mpi_get_nbits (p) - 1;
+ g_return_val_if_fail (bits >= 0, FALSE);
+
+ /*
+ * Generate a strong random number of bits, and not zero.
+ * gcry_mpi_randomize bumps up to the next byte. Since we
+ * need to have a value less than half of p, we make sure
+ * we bump down.
+ */
+ *x = gcry_mpi_snew (bits);
+ g_return_val_if_fail (*x, FALSE);
+ while (gcry_mpi_cmp_ui (*x, 0) == 0)
+ gcry_mpi_randomize (*x, (bits / 8) * 8, GCRY_STRONG_RANDOM);
+
+ *X = gcry_mpi_new (bits);
+ g_return_val_if_fail (*X, FALSE);
+ gcry_mpi_powm (*X, g, *x, p);
+
+ return TRUE;
+}
+
+gboolean
+egg_dh_gen_key (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;
+
+static gboolean
+parse_der_pkcs3 (const guchar *data, gsize n_data, Parameters *params)
+{
+ ASN1_TYPE asn;
+ guchar *buf_p, *buf_g;
+ gsize n_buf_p, n_buf_g;
+ gcry_error_t gcry;
+
+ 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 (¶ms->p, GCRYMPI_FMT_STD, buf_p, n_buf_p, &n_buf_p);
+ g_return_val_if_fail (gcry == 0, FALSE);
+ gcry = gcry_mpi_scan (¶ms->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);
+
+ memset (¶ms, 0, sizeof (params));
+ if (!parse_der_pkcs3 (data, n_data, ¶ms))
+ egg_openssl_pem_parse (data, n_data, parse_openssl_pkcs3, ¶ms);
+
+ if (!params.p || !params.g)
+ return FALSE;
+ *p = params.p;
+ *g = params.g;
+ return TRUE;
+}
diff --git a/egg/egg-dh.h b/egg/egg-dh.h
new file mode 100644
index 0000000..aa92808
--- /dev/null
+++ b/egg/egg-dh.h
@@ -0,0 +1,35 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2009 Stefan Walter
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef EGG_DH_H_
+#define EGG_DH_H_
+
+#include <glib.h>
+
+#include <gcrypt.h>
+
+gboolean egg_dh_gen_secret (gcry_mpi_t p, gcry_mpi_t g, gcry_mpi_t *X, gcry_mpi_t *x);
+
+gboolean egg_dh_gen_key (gcry_mpi_t Y, gcry_mpi_t x, gcry_mpi_t p, gcry_mpi_t *k);
+
+gboolean egg_dh_parse_pkcs3 (const guchar *data, gsize n_data, gcry_mpi_t *p, gcry_mpi_t *g);
+
+#endif /* EGG_DH_H_ */
diff --git a/egg/tests/Makefile.am b/egg/tests/Makefile.am
index b9b490e..50b2d4d 100644
--- a/egg/tests/Makefile.am
+++ b/egg/tests/Makefile.am
@@ -10,6 +10,7 @@ UNIT_AUTO = \
unit-test-secmem.c \
unit-test-symkey.c \
unit-test-openssl.c \
+ unit-test-dh.c
asn1-def-test.h
UNIT_PROMPT =
diff --git a/egg/tests/test-data/dh-params.pem b/egg/tests/test-data/dh-params.pem
new file mode 100644
index 0000000..cc0afd8
--- /dev/null
+++ b/egg/tests/test-data/dh-params.pem
@@ -0,0 +1,5 @@
+-----BEGIN DH PARAMETERS-----
+MIGHAoGBAOmZHLx3BXvrPoFlAl6DOHIr2wApepEOpEESnqhO0JGvnaVWgaGS5+fC
+g/9vqexageA6jAmZ9msZ34C+hn0KebHbPkKufsH8oFeInz7WZuhsPCSKpHyOaZmX
+GDx6gJMkLA10HOXU4bqZy1rOiVxTuS2bn+aw2CA7WoKGVnuOnCozAgEC
+-----END DH PARAMETERS-----
diff --git a/egg/tests/unit-test-dh.c b/egg/tests/unit-test-dh.c
new file mode 100644
index 0000000..a190da3
--- /dev/null
+++ b/egg/tests/unit-test-dh.c
@@ -0,0 +1,89 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* unit-test-dh.c: Test egg-dh.c
+
+ Copyright (C) 2009 Stefan Walter
+
+ The Gnome Keyring Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Keyring Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Stef Walter <stef memberwebs com>
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "run-auto-test.h"
+
+#include "egg-dh.h"
+
+#include <gcrypt.h>
+
+DEFINE_TEST(dh_parse_pkcs3)
+{
+ gcry_mpi_t p, g;
+ guchar *data;
+ gsize n_data;
+ gboolean ret;
+
+ data = test_read_testdata ("dh-params.pem", &n_data);
+ ret = egg_dh_parse_pkcs3 (data, n_data, &p, &g);
+ g_assert (ret == TRUE);
+ g_assert (gcry_mpi_get_nbits (p) == 1024);
+
+ gcry_mpi_release (p);
+ gcry_mpi_release (g);
+ g_free (data);
+}
+
+DEFINE_TEST(dh_perform)
+{
+ guchar *data;
+ gsize n_data;
+ gcry_mpi_t p, g;
+ gcry_mpi_t x1, X1, k1;
+ gcry_mpi_t x2, X2, k2;
+ gboolean ret;
+
+ /* Load up the parameters */
+ data = test_read_testdata ("dh-params.pem", &n_data);
+ if (!egg_dh_parse_pkcs3 (data, n_data, &p, &g))
+ g_assert_not_reached ();
+ g_free (data);
+
+ /* Generate secrets */
+ ret = egg_dh_gen_secret (p, g, &X1, &x1);
+ g_assert (ret);
+ ret = egg_dh_gen_secret (p, g, &X2, &x2);
+ g_assert (ret);
+
+ /* Calculate keys */
+ ret = egg_dh_gen_key (X2, x1, p, &k1);
+ g_assert (ret);
+ ret = egg_dh_gen_key (X1, x2, p, &k2);
+ g_assert (ret);
+
+ /* Keys must be the same */
+ g_assert (gcry_mpi_cmp (k1, k2) == 0);
+
+ gcry_mpi_release (p);
+ gcry_mpi_release (g);
+ gcry_mpi_release (x1);
+ gcry_mpi_release (X1);
+ gcry_mpi_release (k1);
+ gcry_mpi_release (x2);
+ gcry_mpi_release (X2);
+ gcry_mpi_release (k2);
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]