[libgnome-keyring/with-hkdf] Use HKDF for digesting of DH secret key.
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgnome-keyring/with-hkdf] Use HKDF for digesting of DH secret key.
- Date: Sun, 27 Feb 2011 08:24:09 +0000 (UTC)
commit 100aa1788d784334247b095ae6a1c621e539ba94
Author: Stef Walter <stefw collabora co uk>
Date: Wed Feb 23 12:34:39 2011 +0100
Use HKDF for digesting of DH secret key.
* Previously we truncated the key, which was broken.
* Secret service spec has been updated.
* Now we use HKDF + SHA256 to digest the DH secret key into the right
size usable by AES.
* The library temporarily still supports the old method in case
its talking to a daemon that doesn't support this fix.
.gitignore | 2 +
configure.in | 4 +
egg/Makefile.am | 3 +-
egg/egg-dh.c | 16 +--
egg/egg-dh.h | 2 +-
egg/egg-hkdf.c | 109 ++++++++++++
egg/egg-hkdf.h | 39 +++++
egg/egg-testing.c | 72 ++++++++
egg/egg-testing.h | 14 ++
egg/tests/Makefile.am | 5 +
egg/tests/test-dh.c | 8 +-
egg/tests/test-hkdf.c | 345 +++++++++++++++++++++++++++++++++++++++
library/gkr-session.c | 173 +++++++++++++++++++-
library/tests/Makefile.am | 3 +-
library/tests/test-any-daemon.c | 78 +++++++++
15 files changed, 847 insertions(+), 26 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index f193699..bf96df7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -103,6 +103,7 @@ run-auto-test.h
/egg/tests/Makefile.in
/egg/tests/test-dh
/egg/tests/test-secmem
+/egg/tests/test-hkdf
# /library
/library/*.pc
@@ -112,6 +113,7 @@ run-auto-test.h
# /library/tests
/library/tests/Makefile
/library/tests/Makefile.in
+/library/tests/test-any-daemon
/library/tests/test-prompting
/library/tests/test-keyrings
/library/tests/test-memory
diff --git a/configure.in b/configure.in
index bacdf7a..dd70207 100644
--- a/configure.in
+++ b/configure.in
@@ -24,6 +24,10 @@ AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
LIB_GNOME_KEYRING_LT_VERSION=1:1:1
AC_SUBST(LIB_GNOME_KEYRING_LT_VERSION)
+version_bits=`echo $VERSION | tr '.' ' '`
+full_version=`printf %03d%03d%03d $version_bits`
+AC_DEFINE_UNQUOTED(GKR_VERSION, $full_version, [The libgnome-keyring version as a number])
+
AC_TYPE_PID_T
AC_TYPE_SIGNAL
AC_TYPE_SIZE_T
diff --git a/egg/Makefile.am b/egg/Makefile.am
index 7fce691..ee0c111 100644
--- a/egg/Makefile.am
+++ b/egg/Makefile.am
@@ -14,9 +14,10 @@ libegg_la_CFLAGS = \
libegg_la_SOURCES = \
egg-dbus.c egg-dbus.h \
egg-dh.c egg-dh.h \
+ egg-hkdf.c egg-hkdf.h \
egg-libgcrypt.c egg-libgcrypt.h \
egg-secure-memory.c egg-secure-memory.h \
- egg-testing.h
+ egg-testing.c egg-testing.h
# -------------------------------------------------------------------
diff --git a/egg/egg-dh.c b/egg/egg-dh.c
index d192aeb..bed524e 100644
--- a/egg/egg-dh.c
+++ b/egg/egg-dh.c
@@ -306,12 +306,11 @@ egg_dh_gen_pair (gcry_mpi_t prime, gcry_mpi_t base, guint bits,
gpointer
egg_dh_gen_secret (gcry_mpi_t peer, gcry_mpi_t priv,
- gcry_mpi_t prime, gsize bytes)
+ gcry_mpi_t prime, gsize *bytes)
{
gcry_error_t gcry;
guchar *value;
gsize n_value;
- gsize offset = 0;
gcry_mpi_t k;
gint bits;
@@ -329,11 +328,8 @@ egg_dh_gen_secret (gcry_mpi_t peer, gcry_mpi_t priv,
/* 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);
+ value = egg_secure_alloc (n_value);
+ gcry = gcry_mpi_print (GCRYMPI_FMT_USG, value, n_value, &n_value, k);
g_return_val_if_fail (gcry == 0, NULL);
#if DEBUG_DH_SECRET
@@ -342,11 +338,7 @@ egg_dh_gen_secret (gcry_mpi_t peer, gcry_mpi_t priv,
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);
- }
+ *bytes = n_value;
#if DEBUG_DH_SECRET
gcry_mpi_scan (&k, GCRYMPI_FMT_USG, value, bytes, NULL);
diff --git a/egg/egg-dh.h b/egg/egg-dh.h
index cfdb3d0..ee315e2 100644
--- a/egg/egg-dh.h
+++ b/egg/egg-dh.h
@@ -45,6 +45,6 @@ gboolean egg_dh_gen_pair (gcry_mpi_t prime,
gpointer egg_dh_gen_secret (gcry_mpi_t peer,
gcry_mpi_t priv,
gcry_mpi_t prime,
- gsize bytes);
+ gsize *bytes);
#endif /* EGG_DH_H_ */
diff --git a/egg/egg-hkdf.c b/egg/egg-hkdf.c
new file mode 100644
index 0000000..eaa90fc
--- /dev/null
+++ b/egg/egg-hkdf.c
@@ -0,0 +1,109 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * 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.
+ *
+ * Author: Stef Walter <stefw collabora co uk>
+ */
+
+#include "config.h"
+
+#include "egg-hkdf.h"
+#include "egg-secure-memory.h"
+
+#include <gcrypt.h>
+
+#include <string.h>
+
+gboolean
+egg_hkdf_perform (const gchar *hash_algo, gconstpointer input, gsize n_input,
+ gconstpointer salt, gsize n_salt, gconstpointer info,
+ gsize n_info, gpointer output, gsize n_output)
+{
+ gpointer alloc = NULL;
+ gpointer buffer = NULL;
+ gcry_md_hd_t md1, md2;
+ guint hash_len;
+ guchar i;
+ gint flags, algo;
+ gsize step, n_buffer;
+ guchar *at;
+ gcry_error_t gcry;
+
+ algo = gcry_md_map_name (hash_algo);
+ g_return_val_if_fail (algo != 0, FALSE);
+
+ hash_len = gcry_md_get_algo_dlen (algo);
+ g_return_val_if_fail (hash_len != 0, FALSE);
+ g_return_val_if_fail (n_output <= 255 * hash_len, FALSE);
+
+ /* Buffer we need to for intermediate stuff */
+ if (gcry_is_secure (input)) {
+ flags = GCRY_MD_FLAG_SECURE;
+ buffer = gcry_malloc_secure (hash_len);
+ } else {
+ flags = 0;
+ buffer = gcry_malloc (hash_len);
+ }
+
+ g_return_val_if_fail (buffer, FALSE);
+ n_buffer = 0;
+
+ /* Salt defaults to hash_len zeros */
+ if (!salt) {
+ salt = alloc = g_malloc0 (hash_len);
+ n_salt = hash_len;
+ }
+
+ /* Step 1: Extract */
+ gcry = gcry_md_open (&md1, algo, GCRY_MD_FLAG_HMAC);
+ g_return_val_if_fail (gcry == 0, FALSE);
+ gcry = gcry_md_setkey (md1, salt, n_salt);
+ g_return_val_if_fail (gcry == 0, FALSE);
+ gcry_md_write (md1, input, n_input);
+
+ /* Step 2: Expand */
+ gcry = gcry_md_open (&md2, algo, GCRY_MD_FLAG_HMAC);
+ g_return_val_if_fail (gcry == 0, FALSE);
+ gcry = gcry_md_setkey (md2, gcry_md_read (md1, algo), hash_len);
+ g_return_val_if_fail (gcry == 0, FALSE);
+ gcry_md_close (md1);
+
+ at = output;
+ for (i = 1; i < 256; ++i) {
+ gcry_md_reset (md2);
+ gcry_md_write (md2, buffer, n_buffer);
+ gcry_md_write (md2, info, n_info);
+ gcry_md_write (md2, &i, 1);
+
+ n_buffer = hash_len;
+ memcpy (buffer, gcry_md_read (md2, algo), n_buffer);
+
+ step = MIN (n_buffer, n_output);
+ memcpy (at, buffer, step);
+ n_output -= step;
+ at += step;
+
+ if (!n_output)
+ break;
+ }
+
+ g_free (alloc);
+ gcry_free (buffer);
+ return TRUE;
+}
diff --git a/egg/egg-hkdf.h b/egg/egg-hkdf.h
new file mode 100644
index 0000000..430d331
--- /dev/null
+++ b/egg/egg-hkdf.h
@@ -0,0 +1,39 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * 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.
+ *
+ * Author: Stef Walter <stefw collabora co uk>
+ */
+
+#ifndef EGG_HKDF_H_
+#define EGG_HKDF_H_
+
+#include <glib.h>
+
+gboolean egg_hkdf_perform (const gchar *hash_algo,
+ gconstpointer input,
+ gsize n_input,
+ gconstpointer salt,
+ gsize n_salt,
+ gconstpointer info,
+ gsize n_info,
+ gpointer output,
+ gsize n_output);
+
+#endif /* EGG_HKDF_H_ */
diff --git a/egg/egg-testing.c b/egg/egg-testing.c
new file mode 100644
index 0000000..458b71f
--- /dev/null
+++ b/egg/egg-testing.c
@@ -0,0 +1,72 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * 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.
+ *
+ * Stef Walter <stefw collabora co uk>
+ */
+
+#include "config.h"
+
+#include "egg-testing.h"
+
+static const char HEXC[] = "0123456789ABCDEF";
+
+static gchar*
+hex_dump (const guchar *data, gsize n_data)
+{
+ GString *result;
+ gsize i;
+ guchar j;
+
+ g_assert (data);
+
+ result = g_string_sized_new (n_data * 2 + 1);
+ for (i = 0; i < n_data; ++i) {
+ g_string_append (result, "\\x");
+
+ j = data[i] >> 4 & 0xf;
+ g_string_append_c (result, HEXC[j]);
+ j = data[i] & 0xf;
+ g_string_append_c (result, HEXC[j]);
+ }
+
+ return g_string_free (result, FALSE);
+}
+
+void
+egg_assertion_message_cmpmem (const char *domain,
+ const char *file,
+ int line,
+ const char *func,
+ const char *expr,
+ gconstpointer arg1,
+ gsize n_arg1,
+ const char *cmp,
+ gconstpointer arg2,
+ gsize n_arg2)
+{
+ char *a1, *a2, *s;
+ a1 = arg1 ? hex_dump (arg1, n_arg1) : g_strdup ("NULL");
+ a2 = arg2 ? hex_dump (arg2, n_arg2) : g_strdup ("NULL");
+ s = g_strdup_printf ("assertion failed (%s): (%s %s %s)", expr, a1, cmp, a2);
+ g_free (a1);
+ g_free (a2);
+ g_assertion_message (domain, file, line, func, s);
+ g_free (s);
+}
diff --git a/egg/egg-testing.h b/egg/egg-testing.h
index ef27cfe..14bc8e9 100644
--- a/egg/egg-testing.h
+++ b/egg/egg-testing.h
@@ -25,8 +25,22 @@
#define EGG_TESTING_H_
#include <glib.h>
+#include <string.h>
#define egg_assert_cmpsize(a, o, b) \
g_assert_cmpuint ((guint)(a), o, (guint)(b))
+#define egg_assert_cmpmem(a, na, cmp, b, nb) \
+ do { gconstpointer __p1 = (a), __p2 = (b); gsize __n1 = (na), __n2 = (nb); \
+ if (__n1 cmp __n2 && memcmp (__p1, __p2, __n1) cmp 0) ; else \
+ egg_assertion_message_cmpmem (G_LOG_DOMAIN, __FILE__, __LINE__, \
+ G_STRFUNC, #a "[" #na"] " #cmp " " #b "[" #nb "]", \
+ __p1, __n1, #cmp, __p2, __n2); } while (0)
+
+void egg_assertion_message_cmpmem (const char *domain, const char *file,
+ int line, const char *func,
+ const char *expr, gconstpointer arg1,
+ gsize n_arg1, const char *cmp,
+ gconstpointer arg2, gsize n_arg2);
+
#endif /* EGG_DH_H_ */
diff --git a/egg/tests/Makefile.am b/egg/tests/Makefile.am
index 13fd068..240fad0 100644
--- a/egg/tests/Makefile.am
+++ b/egg/tests/Makefile.am
@@ -9,6 +9,7 @@ LDADD = \
TEST_PROGS = \
test-dh \
+ test-hkdf \
test-secmem
check_PROGRAMS = $(TEST_PROGS)
@@ -17,3 +18,7 @@ test: ${TEST_PROGS}
gtester -k --verbose ${TEST_PROGS}
check-local: test
+
+if WITH_TESTS
+all-local: $(check_PROGRAMS)
+endif
diff --git a/egg/tests/test-dh.c b/egg/tests/test-dh.c
index 81cf0d7..4a62fd1 100644
--- a/egg/tests/test-dh.c
+++ b/egg/tests/test-dh.c
@@ -44,6 +44,7 @@ test_dh_perform (void)
gcry_mpi_t x2, X2;
gpointer k1, k2;
gboolean ret;
+ gsize n1, n2;
/* Load up the parameters */
if (!egg_dh_default_params ("ietf-ike-grp-modp-768", &p, &g))
@@ -56,13 +57,14 @@ test_dh_perform (void)
g_assert (ret);
/* Calculate keys */
- k1 = egg_dh_gen_secret (X2, x1, p, 96);
+ k1 = egg_dh_gen_secret (X2, x1, p, &n1);
g_assert (k1);
- k2 = egg_dh_gen_secret (X1, x2, p, 96);
+ k2 = egg_dh_gen_secret (X1, x2, p, &n2);
g_assert (k2);
/* Keys must be the same */
- g_assert (memcmp (k1, k2, 96) == 0);
+ egg_assert_cmpsize (n1, ==, n2);
+ g_assert (memcmp (k1, k2, n1) == 0);
gcry_mpi_release (p);
gcry_mpi_release (g);
diff --git a/egg/tests/test-hkdf.c b/egg/tests/test-hkdf.c
new file mode 100644
index 0000000..44c463d
--- /dev/null
+++ b/egg/tests/test-hkdf.c
@@ -0,0 +1,345 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* test-hkdf.c: Test egg-hkdf.c
+
+ Copyright (C) 2011 Collabora Ltd.
+
+ 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 collabora co uk>
+*/
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "egg-hkdf.h"
+#include "egg-secure-memory.h"
+#include "egg-testing.h"
+
+#include <gcrypt.h>
+
+EGG_SECURE_GLIB_DEFINITIONS ();
+
+static void
+test_hkdf_test_case_1 (void)
+{
+ /* RFC 5869: A.1 Test Case 1 */
+ const guchar ikm[] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b };
+ const guchar salt[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c };
+ const guchar info[] = { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9 };
+ const guchar okm[] = { 0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a,
+ 0x90, 0x43, 0x4f, 0x64, 0xd0, 0x36, 0x2f, 0x2a,
+ 0x2d, 0x2d, 0x0a, 0x90, 0xcf, 0x1a, 0x5a, 0x4c,
+ 0x5d, 0xb0, 0x2d, 0x56, 0xec, 0xc4, 0xc5, 0xbf,
+ 0x34, 0x00, 0x72, 0x08, 0xd5, 0xb8, 0x87, 0x18,
+ 0x58, 0x65 };
+ guchar buffer[sizeof (okm)];
+ gboolean ret;
+
+ egg_assert_cmpsize (sizeof (ikm), ==, 22);
+ egg_assert_cmpsize (sizeof (salt), ==, 13);
+ egg_assert_cmpsize (sizeof (info), ==, 10);
+ egg_assert_cmpsize (sizeof (okm), ==, 42);
+
+ memset (buffer, 0, sizeof (buffer));
+ ret = egg_hkdf_perform ("sha256",
+ ikm, sizeof (ikm),
+ salt, sizeof (salt),
+ info, sizeof (info),
+ buffer, sizeof (buffer));
+ g_assert (ret);
+ egg_assert_cmpmem (buffer, sizeof (buffer), ==, okm, sizeof (okm));
+}
+
+static void
+test_hkdf_test_case_2 (void)
+{
+ /* RFC 5869: A.2 Test Case 2 */
+ const guchar ikm[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f };
+ const guchar salt[] = { 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+ 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf };
+ const guchar info[] = { 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff };
+ const guchar okm[] = { 0xb1, 0x1e, 0x39, 0x8d, 0xc8, 0x03, 0x27, 0xa1,
+ 0xc8, 0xe7, 0xf7, 0x8c, 0x59, 0x6a, 0x49, 0x34,
+ 0x4f, 0x01, 0x2e, 0xda, 0x2d, 0x4e, 0xfa, 0xd8,
+ 0xa0, 0x50, 0xcc, 0x4c, 0x19, 0xaf, 0xa9, 0x7c,
+ 0x59, 0x04, 0x5a, 0x99, 0xca, 0xc7, 0x82, 0x72,
+ 0x71, 0xcb, 0x41, 0xc6, 0x5e, 0x59, 0x0e, 0x09,
+ 0xda, 0x32, 0x75, 0x60, 0x0c, 0x2f, 0x09, 0xb8,
+ 0x36, 0x77, 0x93, 0xa9, 0xac, 0xa3, 0xdb, 0x71,
+ 0xcc, 0x30, 0xc5, 0x81, 0x79, 0xec, 0x3e, 0x87,
+ 0xc1, 0x4c, 0x01, 0xd5, 0xc1, 0xf3, 0x43, 0x4f,
+ 0x1d, 0x87 };
+ guchar buffer[sizeof (okm)];
+ gboolean ret;
+
+ egg_assert_cmpsize (sizeof (ikm), ==, 80);
+ egg_assert_cmpsize (sizeof (salt), ==, 80);
+ egg_assert_cmpsize (sizeof (info), ==, 80);
+ egg_assert_cmpsize (sizeof (okm), ==, 82);
+
+ memset (buffer, 0, sizeof (buffer));
+ ret = egg_hkdf_perform ("sha256",
+ ikm, sizeof (ikm),
+ salt, sizeof (salt),
+ info, sizeof (info),
+ buffer, sizeof (buffer));
+ g_assert (ret);
+ egg_assert_cmpmem (buffer, sizeof (buffer), ==, okm, sizeof (okm));
+}
+
+static void
+test_hkdf_test_case_3 (void)
+{
+ /* RFC 5869: A.3 Test Case 3 */
+ const guchar ikm[] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,};
+ const guchar salt[] = { };
+ const guchar info[] = { };
+ const guchar okm[] = { 0x8d, 0xa4, 0xe7, 0x75, 0xa5, 0x63, 0xc1, 0x8f,
+ 0x71, 0x5f, 0x80, 0x2a, 0x06, 0x3c, 0x5a, 0x31,
+ 0xb8, 0xa1, 0x1f, 0x5c, 0x5e, 0xe1, 0x87, 0x9e,
+ 0xc3, 0x45, 0x4e, 0x5f, 0x3c, 0x73, 0x8d, 0x2d,
+ 0x9d, 0x20, 0x13, 0x95, 0xfa, 0xa4, 0xb6, 0x1a,
+ 0x96, 0xc8 };
+ guchar buffer[sizeof (okm)];
+ gboolean ret;
+
+ egg_assert_cmpsize (sizeof (ikm), ==, 22);
+ egg_assert_cmpsize (sizeof (salt), ==, 0);
+ egg_assert_cmpsize (sizeof (info), ==, 0);
+ egg_assert_cmpsize (sizeof (okm), ==, 42);
+
+ memset (buffer, 0, sizeof (buffer));
+ ret = egg_hkdf_perform ("sha256",
+ ikm, sizeof (ikm),
+ salt, sizeof (salt),
+ info, sizeof (info),
+ buffer, sizeof (buffer));
+ g_assert (ret);
+ egg_assert_cmpmem (buffer, sizeof (buffer), ==, okm, sizeof (okm));
+}
+
+static void
+test_hkdf_test_case_4 (void)
+{
+ /* RFC 5869: A.4 Test Case 4 */
+ const guchar ikm[] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b };
+ const guchar salt[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c };
+ const guchar info[] = { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9 };
+ const guchar okm[] = { 0x08, 0x5a, 0x01, 0xea, 0x1b, 0x10, 0xf3, 0x69,
+ 0x33, 0x06, 0x8b, 0x56, 0xef, 0xa5, 0xad, 0x81,
+ 0xa4, 0xf1, 0x4b, 0x82, 0x2f, 0x5b, 0x09, 0x15,
+ 0x68, 0xa9, 0xcd, 0xd4, 0xf1, 0x55, 0xfd, 0xa2,
+ 0xc2, 0x2e, 0x42, 0x24, 0x78, 0xd3, 0x05, 0xf3,
+ 0xf8, 0x96 };
+ guchar buffer[sizeof (okm)];
+ gboolean ret;
+
+ egg_assert_cmpsize (sizeof (ikm), ==, 11);
+ egg_assert_cmpsize (sizeof (salt), ==, 13);
+ egg_assert_cmpsize (sizeof (info), ==, 10);
+ egg_assert_cmpsize (sizeof (okm), ==, 42);
+
+ memset (buffer, 0, sizeof (buffer));
+ ret = egg_hkdf_perform ("sha1",
+ ikm, sizeof (ikm),
+ salt, sizeof (salt),
+ info, sizeof (info),
+ buffer, sizeof (buffer));
+ g_assert (ret);
+ egg_assert_cmpmem (buffer, sizeof (buffer), ==, okm, sizeof (okm));
+}
+
+static void
+test_hkdf_test_case_5 (void)
+{
+ /* RFC 5869: A.5 Test Case 5 */
+ const guchar ikm[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f };
+ const guchar salt[] = { 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+ 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf };
+ const guchar info[] = { 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff };
+ const guchar okm[] = { 0x0b, 0xd7, 0x70, 0xa7, 0x4d, 0x11, 0x60, 0xf7,
+ 0xc9, 0xf1, 0x2c, 0xd5, 0x91, 0x2a, 0x06, 0xeb,
+ 0xff, 0x6a, 0xdc, 0xae, 0x89, 0x9d, 0x92, 0x19,
+ 0x1f, 0xe4, 0x30, 0x56, 0x73, 0xba, 0x2f, 0xfe,
+ 0x8f, 0xa3, 0xf1, 0xa4, 0xe5, 0xad, 0x79, 0xf3,
+ 0xf3, 0x34, 0xb3, 0xb2, 0x02, 0xb2, 0x17, 0x3c,
+ 0x48, 0x6e, 0xa3, 0x7c, 0xe3, 0xd3, 0x97, 0xed,
+ 0x03, 0x4c, 0x7f, 0x9d, 0xfe, 0xb1, 0x5c, 0x5e,
+ 0x92, 0x73, 0x36, 0xd0, 0x44, 0x1f, 0x4c, 0x43,
+ 0x00, 0xe2, 0xcf, 0xf0, 0xd0, 0x90, 0x0b, 0x52,
+ 0xd3, 0xb4 };
+ guchar buffer[sizeof (okm)];
+ gboolean ret;
+
+ egg_assert_cmpsize (sizeof (ikm), ==, 80);
+ egg_assert_cmpsize (sizeof (salt), ==, 80);
+ egg_assert_cmpsize (sizeof (info), ==, 80);
+ egg_assert_cmpsize (sizeof (okm), ==, 82);
+
+ memset (buffer, 0, sizeof (buffer));
+ ret = egg_hkdf_perform ("sha1",
+ ikm, sizeof (ikm),
+ salt, sizeof (salt),
+ info, sizeof (info),
+ buffer, sizeof (buffer));
+ g_assert (ret);
+ egg_assert_cmpmem (buffer, sizeof (buffer), ==, okm, sizeof (okm));
+}
+
+static void
+test_hkdf_test_case_6 (void)
+{
+ /* RFC 5869: A.6 Test Case 6 */
+ const guchar ikm[] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b };
+ const guchar salt[] = { };
+ const guchar info[] = { };
+ const guchar okm[] = { 0x0a, 0xc1, 0xaf, 0x70, 0x02, 0xb3, 0xd7, 0x61,
+ 0xd1, 0xe5, 0x52, 0x98, 0xda, 0x9d, 0x05, 0x06,
+ 0xb9, 0xae, 0x52, 0x05, 0x72, 0x20, 0xa3, 0x06,
+ 0xe0, 0x7b, 0x6b, 0x87, 0xe8, 0xdf, 0x21, 0xd0,
+ 0xea, 0x00, 0x03, 0x3d, 0xe0, 0x39, 0x84, 0xd3,
+ 0x49, 0x18 };
+ guchar buffer[sizeof (okm)];
+ gboolean ret;
+
+ egg_assert_cmpsize (sizeof (ikm), ==, 22);
+ egg_assert_cmpsize (sizeof (salt), ==, 0);
+ egg_assert_cmpsize (sizeof (info), ==, 0);
+ egg_assert_cmpsize (sizeof (okm), ==, 42);
+
+ memset (buffer, 0, sizeof (buffer));
+ ret = egg_hkdf_perform ("sha1",
+ ikm, sizeof (ikm),
+ salt, sizeof (salt),
+ info, sizeof (info),
+ buffer, sizeof (buffer));
+ g_assert (ret);
+ egg_assert_cmpmem (buffer, sizeof (buffer), ==, okm, sizeof (okm));
+}
+
+static void
+test_hkdf_test_case_7 (void)
+{
+ /* RFC 5869: A.7 Test Case 7 */
+ const guchar ikm[] = { 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c };
+ const guchar *salt = NULL;
+ const guchar info[] = { };
+ const guchar okm[] = { 0x2c, 0x91, 0x11, 0x72, 0x04, 0xd7, 0x45, 0xf3,
+ 0x50, 0x0d, 0x63, 0x6a, 0x62, 0xf6, 0x4f, 0x0a,
+ 0xb3, 0xba, 0xe5, 0x48, 0xaa, 0x53, 0xd4, 0x23,
+ 0xb0, 0xd1, 0xf2, 0x7e, 0xbb, 0xa6, 0xf5, 0xe5,
+ 0x67, 0x3a, 0x08, 0x1d, 0x70, 0xcc, 0xe7, 0xac,
+ 0xfc, 0x48 };
+ guchar buffer[sizeof (okm)];
+ gboolean ret;
+
+ egg_assert_cmpsize (sizeof (ikm), ==, 22);
+ egg_assert_cmpsize (sizeof (info), ==, 0);
+ egg_assert_cmpsize (sizeof (okm), ==, 42);
+
+ memset (buffer, 0, sizeof (buffer));
+ ret = egg_hkdf_perform ("sha1",
+ ikm, sizeof (ikm),
+ salt, sizeof (salt),
+ info, sizeof (info),
+ buffer, sizeof (buffer));
+ g_assert (ret);
+ egg_assert_cmpmem (buffer, sizeof (buffer), ==, okm, sizeof (okm));
+}
+
+int
+main (int argc, char **argv)
+{
+ g_test_init (&argc, &argv, NULL);
+
+ g_test_add_func ("/hkdf/test-case-1", test_hkdf_test_case_1);
+ g_test_add_func ("/hkdf/test-case-2", test_hkdf_test_case_2);
+ g_test_add_func ("/hkdf/test-case-3", test_hkdf_test_case_3);
+ g_test_add_func ("/hkdf/test-case-4", test_hkdf_test_case_4);
+ g_test_add_func ("/hkdf/test-case-5", test_hkdf_test_case_5);
+ g_test_add_func ("/hkdf/test-case-6", test_hkdf_test_case_6);
+ g_test_add_func ("/hkdf/test-case-7", test_hkdf_test_case_7);
+
+ return g_test_run ();
+}
diff --git a/library/gkr-session.c b/library/gkr-session.c
index 9869f59..9fc5332 100644
--- a/library/gkr-session.c
+++ b/library/gkr-session.c
@@ -30,6 +30,7 @@
#include <gcrypt.h>
#include "egg/egg-dh.h"
+#include "egg/egg-hkdf.h"
#include "egg/egg-libgcrypt.h"
#include "egg/egg-secure-memory.h"
@@ -256,19 +257,42 @@ decode_open_session_aes (DBusMessage *message, gcry_mpi_t *peer, const char **pa
return (gcry == 0);
}
+/*
+ * This less secure algorithm is supported by some old versions of
+ * gnome-keyring-daemon. We support it purely as an interim thing,
+ * while all version of gnome-keyring-daemon are being upgraded.
+ */
+
+#if GKR_VERSION >= 003001000
+ #error "Support for dh-ietf1024-aes128-cbc-pkcs7 should be removed in 3.1.x"
+#else
+
+static gboolean
+reply_says_not_supported (DBusMessage *reply)
+{
+ /*
+ * In old versions of the spec we used
+ * org.freedesktop.Secret.Error.NotSupported instead of the standard
+ * dbus not supported error.
+ */
+ return (dbus_message_is_error (reply, DBUS_ERROR_NOT_SUPPORTED) ||
+ dbus_message_is_error (reply, "org.freedesktop.Secret.Error.NotSupported"));
+}
+
static void
-on_open_session_aes (GkrOperation *op, DBusMessage *reply, gpointer user_data)
+on_open_session_broken (GkrOperation *op, DBusMessage *reply, gpointer user_data)
{
gcry_mpi_t priv, prime, peer;
GkrSession *session;
const char *path;
- gpointer key;
+ gpointer ikm;
+ gsize n_ikm;
g_assert (op);
g_assert (user_data);
- /* If AES is not supported then skip on over to plain */
- if (dbus_message_is_error (reply, DBUS_ERROR_NOT_SUPPORTED)) {
+ /* If 'broken' is not supported then skip on over to plain */
+ if (reply_says_not_supported (reply)) {
session_negotiate_plain (op);
return;
}
@@ -287,13 +311,14 @@ on_open_session_aes (GkrOperation *op, DBusMessage *reply, gpointer user_data)
if (!egg_dh_default_params ("ietf-ike-grp-modp-1024", &prime, NULL))
g_return_if_reached ();
+ /* Generate the actual secret */
priv = user_data;
- key = egg_dh_gen_secret (peer, priv, prime, 16);
+ ikm = egg_dh_gen_secret (peer, priv, prime, &n_ikm);
gcry_mpi_release (peer);
gcry_mpi_release (prime);
- if (key == NULL) {
+ if (ikm == NULL) {
g_message ("couldn't negotiate a valid session key");
gkr_operation_complete (op, GNOME_KEYRING_RESULT_IO_ERROR);
return;
@@ -301,9 +326,141 @@ on_open_session_aes (GkrOperation *op, DBusMessage *reply, gpointer user_data)
session = session_new ();
session->path = g_strdup (path);
- session->key = key;
session->n_key = 16;
+ /* Now truncate this into our aes key. This is the 'broken' part*/
+ session->key = egg_secure_alloc (session->n_key);
+ g_assert (session->n_key < n_ikm);
+ memcpy (session->key, (guchar*)ikm + (n_ikm - session->n_key),
+ session->n_key);
+ egg_secure_free (ikm);
+
+ G_LOCK (session_globals);
+ {
+ if (the_session)
+ gkr_session_unref (the_session);
+ the_session = gkr_session_ref (session);
+ }
+ G_UNLOCK (session_globals);
+
+ gkr_callback_invoke_op_session (gkr_operation_pop (op), session);
+ gkr_session_unref (session);
+}
+
+static void
+session_negotiate_broken (GkrOperation *op)
+{
+ /* The old broken algorithm, without digesting the dh result */
+ const char *algorithm = "dh-ietf1024-aes128-cbc-pkcs7";
+ DBusMessageIter iter, variant, array;
+ gcry_mpi_t prime, base, pub, priv;
+ gboolean ret;
+ guchar *buffer;
+ gsize n_buffer;
+ gcry_error_t gcry;
+ DBusMessage *req;
+
+ g_assert (op);
+
+ egg_libgcrypt_initialize ();
+
+ prime = base = pub = priv = NULL;
+ ret = egg_dh_default_params ("ietf-ike-grp-modp-1024", &prime, &base) &&
+ egg_dh_gen_pair (prime, base, 0, &pub, &priv);
+
+ gcry_mpi_release (prime);
+ gcry_mpi_release (base);
+
+ if (ret == TRUE) {
+ req = dbus_message_new_method_call (gkr_service_name (), SERVICE_PATH,
+ SERVICE_INTERFACE, "OpenSession");
+
+ dbus_message_iter_init_append (req, &iter);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &algorithm);
+ dbus_message_iter_open_container (&iter, DBUS_TYPE_VARIANT, "ay", &variant);
+ dbus_message_iter_open_container (&variant, DBUS_TYPE_ARRAY, "y", &array);
+
+ gcry = gcry_mpi_aprint (GCRYMPI_FMT_USG, &buffer, &n_buffer, pub);
+ g_return_if_fail (gcry == 0);
+ dbus_message_iter_append_fixed_array (&array, DBUS_TYPE_BYTE, &buffer, n_buffer);
+ gcry_free (buffer);
+
+ dbus_message_iter_close_container (&variant, &array);
+ dbus_message_iter_close_container (&iter, &variant);
+
+ gkr_operation_push (op, on_open_session_broken, GKR_CALLBACK_OP_MSG,
+ priv, (GDestroyNotify)gcry_mpi_release);
+ priv = NULL;
+
+ gkr_operation_request (op, req);
+ dbus_message_unref (req);
+ }
+
+ gcry_mpi_release (pub);
+ gcry_mpi_release (priv);
+
+ if (ret == FALSE)
+ gkr_operation_complete_later (op, GNOME_KEYRING_RESULT_IO_ERROR);
+}
+
+#endif /* GKR_VERSION >= 003001000 */
+
+static void
+on_open_session_aes (GkrOperation *op, DBusMessage *reply, gpointer user_data)
+{
+ gcry_mpi_t priv, prime, peer;
+ GkrSession *session;
+ const char *path;
+ gpointer ikm;
+ gsize n_ikm;
+
+ g_assert (op);
+ g_assert (user_data);
+
+ /* If AES is not supported then try the old 'broken' method */
+ if (reply_says_not_supported (reply)) {
+ session_negotiate_broken (op);
+ return;
+ }
+
+ /* Handle any other errors */
+ if (gkr_operation_handle_errors (op, reply))
+ return;
+
+ /* Parse the result from OpenSession */
+ if (!decode_open_session_aes (reply, &peer, &path)) {
+ g_message ("received an invalid response to Service.OpenSession()");
+ gkr_operation_complete (op, GNOME_KEYRING_RESULT_IO_ERROR);
+ return;
+ }
+
+ if (!egg_dh_default_params ("ietf-ike-grp-modp-1024", &prime, NULL))
+ g_return_if_reached ();
+
+ /* Generate the actual secret */
+ priv = user_data;
+ ikm = egg_dh_gen_secret (peer, priv, prime, &n_ikm);
+
+ gcry_mpi_release (peer);
+ gcry_mpi_release (prime);
+
+ if (ikm == NULL) {
+ g_message ("couldn't negotiate a valid session key");
+ gkr_operation_complete (op, GNOME_KEYRING_RESULT_IO_ERROR);
+ return;
+ }
+
+ session = session_new ();
+ session->path = g_strdup (path);
+ session->n_key = 16;
+
+ /* Now digest this into our aes key */
+ 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_if_reached ();
+ egg_secure_free (ikm);
+
G_LOCK (session_globals);
{
if (the_session)
@@ -319,9 +476,9 @@ on_open_session_aes (GkrOperation *op, DBusMessage *reply, gpointer user_data)
static void
session_negotiate_aes (GkrOperation *op)
{
+ const char *algorithm = "dh-ietf1024-sha256-aes128-cbc-pkcs7";
DBusMessageIter iter, variant, array;
gcry_mpi_t prime, base, pub, priv;
- const char *algorithm = "dh-ietf1024-aes128-cbc-pkcs7";
gboolean ret;
guchar *buffer;
gsize n_buffer;
diff --git a/library/tests/Makefile.am b/library/tests/Makefile.am
index 00d3ed5..0909356 100644
--- a/library/tests/Makefile.am
+++ b/library/tests/Makefile.am
@@ -11,7 +11,8 @@ LDADD = \
TEST_PROGS = \
test-memory \
test-keyrings \
- test-other
+ test-other \
+ test-any-daemon
check_PROGRAMS = \
test-prompting \
diff --git a/library/tests/test-any-daemon.c b/library/tests/test-any-daemon.c
new file mode 100644
index 0000000..5561fc0
--- /dev/null
+++ b/library/tests/test-any-daemon.c
@@ -0,0 +1,78 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* test-session.c: Test reading a secret
+
+ Copyright (C) 2011 Collabora Ltd.
+
+ 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 <stefw collabora co uk>
+*/
+
+#include "config.h"
+
+#include "gnome-keyring.h"
+#include <glib.h>
+
+static void
+test_create_find_read_password (void)
+{
+ GnomeKeyringResult res;
+ GnomeKeyringAttributeList* attrs;
+ GnomeKeyringFound* f;
+ guint id;
+ GList *found;
+ guint num;
+
+ /* Unique for every run */
+ num = time (NULL);
+
+ attrs = gnome_keyring_attribute_list_new ();
+ gnome_keyring_attribute_list_append_string (attrs, "dog", "woof");
+ gnome_keyring_attribute_list_append_string (attrs, "bird", "cheep");
+ gnome_keyring_attribute_list_append_string (attrs, "iguana", "");
+ gnome_keyring_attribute_list_append_uint32 (attrs, "num", num);
+
+ /* Create the item */
+ res = gnome_keyring_item_create_sync ("session", GNOME_KEYRING_ITEM_GENERIC_SECRET,
+ "Barnyard", attrs, "the very secret", TRUE, &id);
+ g_assert_cmpint (GNOME_KEYRING_RESULT_OK, ==, res);
+
+ /* Now try to find it */
+ res = gnome_keyring_find_items_sync (GNOME_KEYRING_ITEM_GENERIC_SECRET, attrs, &found);
+ g_assert_cmpint (GNOME_KEYRING_RESULT_OK, ==, res);
+
+ g_assert_cmpint (g_list_length (found), ==, 1);
+ f = (GnomeKeyringFound*)found->data;
+
+ g_assert_cmpstr (f->keyring, ==, "session");
+ g_assert_cmpstr (f->secret, ==, "the very secret");
+
+ gnome_keyring_found_list_free (found);
+}
+
+int
+main (int argc, char **argv)
+{
+ g_test_init (&argc, &argv, NULL);
+
+ if (!gnome_keyring_is_available ()) {
+ g_printerr ("skipping any-daemon tests, no daemon is running");
+ return 0;
+ }
+
+ g_test_add_func ("/any-daemon/create-find-ready-password", test_create_find_read_password);
+ return g_test_run ();
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]