[gnome-keyring] gcr: Refactor GcrSecretExchange
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-keyring] gcr: Refactor GcrSecretExchange
- Date: Sat, 1 Oct 2011 11:19:52 +0000 (UTC)
commit 45ef0a8bcff34b14f3813fea46cb0053b98c9c5b
Author: Stef Walter <stefw collabora co uk>
Date: Sat Aug 20 22:50:42 2011 +0200
gcr: Refactor GcrSecretExchange
* Use the GcrSecretExchange object on both sides.
* Allow exchange of multiple secrets, and in both directions.
* Add tests
.gitignore | 1 +
gcr/gcr-base.h | 2 +
gcr/gcr-secret-exchange.c | 220 +++++++++++++++-----------------------
gcr/gcr-secret-exchange.h | 25 ++---
gcr/tests/Makefile.am | 1 +
gcr/tests/test-secret-exchange.c | 162 ++++++++++++++++++++++++++++
6 files changed, 261 insertions(+), 150 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index a56b81a..b5938d4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -143,6 +143,7 @@ run-tests
/gcr/tests/test-parser
/gcr/tests/test-pkcs11-certificate
/gcr/tests/test-record
+/gcr/tests/test-secret-exchange
/gcr/tests/test-simple-certificate
/gcr/tests/test-trust
/gcr/tests/test-util
diff --git a/gcr/gcr-base.h b/gcr/gcr-base.h
index 54cc629..69133f1 100644
--- a/gcr/gcr-base.h
+++ b/gcr/gcr-base.h
@@ -43,7 +43,9 @@
#include "gcr-library.h"
#include "gcr-parser.h"
#include "gcr-pkcs11-certificate.h"
+#include "gcr-secret-exchange.h"
#include "gcr-simple-certificate.h"
+#include "gcr-simple-collection.h"
#include "gcr-trust.h"
#include "gcr-union-collection.h"
#include "gcr-unlock-options.h"
diff --git a/gcr/gcr-secret-exchange.c b/gcr/gcr-secret-exchange.c
index 768083c..ff5d3e6 100644
--- a/gcr/gcr-secret-exchange.c
+++ b/gcr/gcr-secret-exchange.c
@@ -52,8 +52,10 @@
struct _GcrSecretExchangePrivate {
gcry_mpi_t prime;
gcry_mpi_t base;
+ gcry_mpi_t pub;
gcry_mpi_t priv;
- guchar *secret;
+ gpointer key;
+ gchar *secret;
gsize n_secret;
};
@@ -134,10 +136,6 @@ key_file_get_mpi (GKeyFile *key_file, const gchar *section,
return (gcry == 0) ? mpi : NULL;
}
-/* ----------------------------------------------------------------------------
- * REQUESTER SIDE
- */
-
static void
gcr_secret_exchange_init (GcrSecretExchange *self)
{
@@ -151,10 +149,12 @@ gcr_secret_exchange_init (GcrSecretExchange *self)
static void
clear_secret_exchange (GcrSecretExchange *self)
{
- if (self->pv->priv) {
- gcry_mpi_release (self->pv->priv);
- self->pv->priv = NULL;
- }
+ gcry_mpi_release (self->pv->priv);
+ self->pv->priv = NULL;
+ gcry_mpi_release (self->pv->pub);
+ self->pv->pub = NULL;
+ egg_secure_free (self->pv->key);
+ self->pv->key = NULL;
egg_secure_free (self->pv->secret);
self->pv->secret = NULL;
self->pv->n_secret = 0;
@@ -166,7 +166,8 @@ gcr_secret_exchange_finalize (GObject *obj)
GcrSecretExchange *self = GCR_SECRET_EXCHANGE (obj);
clear_secret_exchange (self);
- gcry_mpi_release (self->pv->priv);
+ gcry_mpi_release (self->pv->prime);
+ gcry_mpi_release (self->pv->base);
G_OBJECT_CLASS (gcr_secret_exchange_parent_class)->finalize (obj);
}
@@ -189,23 +190,23 @@ gcr_secret_exchange_new (void)
}
gchar *
-gcr_secret_exchange_request (GcrSecretExchange *self)
+gcr_secret_exchange_begin (GcrSecretExchange *self)
{
GKeyFile *output;
- gcry_mpi_t pub;
gchar *result;
g_return_val_if_fail (GCR_IS_SECRET_EXCHANGE (self), NULL);
clear_secret_exchange (self);
+ g_assert (self->pv->priv == NULL);
output = g_key_file_new ();
- if (!egg_dh_gen_pair (self->pv->prime, self->pv->base, 0, &pub, &self->pv->priv))
+ if (!egg_dh_gen_pair (self->pv->prime, self->pv->base, 0,
+ &self->pv->pub, &self->pv->priv))
g_return_val_if_reached (NULL);
- key_file_set_mpi (output, EXCHANGE_VERSION, "public", pub);
- gcry_mpi_release (pub);
+ key_file_set_mpi (output, EXCHANGE_VERSION, "public", self->pv->pub);
result = g_key_file_to_data (output, NULL, NULL);
g_return_val_if_fail (result != NULL, NULL);
@@ -215,46 +216,46 @@ gcr_secret_exchange_request (GcrSecretExchange *self)
return result;
}
-static gpointer
-calculate_receive_key (GKeyFile *input, gcry_mpi_t prime, gcry_mpi_t priv)
+static gboolean
+calculate_key (GcrSecretExchange *self,
+ GKeyFile *input)
{
gcry_mpi_t peer;
gpointer ikm;
gsize n_ikm;
- gpointer key;
peer = key_file_get_mpi (input, EXCHANGE_VERSION, "public");
if (peer == NULL) {
g_message ("secret-exchange: invalid or missing 'public' argument");
- return NULL;
+ return FALSE;
}
/* Build up a key we can use */
- ikm = egg_dh_gen_secret (peer, priv, prime, &n_ikm);
- g_return_val_if_fail (ikm != NULL, NULL);
+ ikm = egg_dh_gen_secret (peer, self->pv->priv, self->pv->prime, &n_ikm);
+ g_return_val_if_fail (ikm != NULL, FALSE);
+
+ if (self->pv->key == NULL)
+ self->pv->key = egg_secure_alloc (EXCHANGE_1_KEY_LENGTH);
- key = egg_secure_alloc (EXCHANGE_1_KEY_LENGTH);
if (!egg_hkdf_perform (EXCHANGE_1_HASH_ALGO, ikm, n_ikm, NULL, 0,
- NULL, 0, key, EXCHANGE_1_KEY_LENGTH))
- g_return_val_if_reached (NULL);
+ NULL, 0, self->pv->key, EXCHANGE_1_KEY_LENGTH))
+ g_return_val_if_reached (FALSE);
egg_secure_free (ikm);
gcry_mpi_release (peer);
- return key;
+ return TRUE;
}
static gpointer
-perform_aes_decrypt (GKeyFile *input,
- gcry_mpi_t prime,
- gcry_mpi_t priv,
+perform_aes_decrypt (GcrSecretExchange *self,
+ GKeyFile *input,
gsize *n_secret)
{
gcry_cipher_hd_t cih;
gcry_error_t gcry;
guchar* padded;
guchar* result;
- gpointer key;
gpointer iv;
gpointer value;
gsize n_result;
@@ -268,37 +269,28 @@ perform_aes_decrypt (GKeyFile *input,
return NULL;
}
- value = key_file_get_base64 (input, EXCHANGE_VERSION, "value", &n_value);
+ value = key_file_get_base64 (input, EXCHANGE_VERSION, "secret", &n_value);
if (value == NULL) {
g_message ("secret-exchange: invalid or missing value");
g_free (iv);
return NULL;
}
- key = calculate_receive_key (input, prime, priv);
- if (key == NULL) {
- g_free (iv);
- g_free (value);
- return NULL;
- }
-
gcry = gcry_cipher_open (&cih, EXCHANGE_1_CIPHER_ALGO, EXCHANGE_1_CIPHER_MODE, 0);
if (gcry != 0) {
g_warning ("couldn't create aes cipher context: %s", gcry_strerror (gcry));
- egg_secure_free (key);
g_free (iv);
return FALSE;
}
/* 16 = 128 bits */
- gcry = gcry_cipher_setkey (cih, key, EXCHANGE_1_KEY_LENGTH);
+ gcry = gcry_cipher_setkey (cih, self->pv->key, EXCHANGE_1_KEY_LENGTH);
g_return_val_if_fail (gcry == 0, FALSE);
/* 16 = 128 bits */
gcry = gcry_cipher_setiv (cih, iv, EXCHANGE_1_IV_LENGTH);
g_return_val_if_fail (gcry == 0, FALSE);
- egg_secure_free (key);
g_free (iv);
/* Allocate memory for the result */
@@ -324,36 +316,50 @@ perform_aes_decrypt (GKeyFile *input,
gboolean
gcr_secret_exchange_receive (GcrSecretExchange *self,
- const gchar *response)
+ const gchar *exchange)
{
GKeyFile *input;
- guchar *secret;
+ gchar *secret;
gsize n_secret;
+ gboolean ret;
/* Parse the input */
input = g_key_file_new ();
- if (!g_key_file_load_from_data (input, response, strlen (response),
+ if (!g_key_file_load_from_data (input, exchange, strlen (exchange),
G_KEY_FILE_NONE, NULL)) {
g_key_file_free (input);
- g_message ("couldn't parse secret exchange request data");
+ g_message ("couldn't parse secret exchange data");
return FALSE;
}
- secret = perform_aes_decrypt (input, self->pv->prime, self->pv->priv, &n_secret);
- g_key_file_free (input);
+ if (self->pv->priv == NULL) {
+ if (!egg_dh_gen_pair (self->pv->prime, self->pv->base, 0,
+ &self->pv->pub, &self->pv->priv))
+ g_return_val_if_reached (FALSE);
+ }
+
+ if (!calculate_key (self, input))
+ return FALSE;
- if (secret != NULL) {
- egg_secure_free (self->pv->secret);
- self->pv->secret = secret;
- self->pv->n_secret = n_secret;
+ ret = TRUE;
+
+ if (g_key_file_has_key (input, EXCHANGE_VERSION, "secret", NULL)) {
+ secret = perform_aes_decrypt (self, input, &n_secret);
+ if (secret == NULL) {
+ ret = FALSE;
+ } else {
+ egg_secure_free (self->pv->secret);
+ self->pv->secret = secret;
+ self->pv->n_secret = n_secret;
+ }
}
- return (secret != NULL);
+ return ret;
}
-const guchar *
-gcr_secret_exchange_get_response (GcrSecretExchange *self,
- gsize *secret_len)
+const gchar *
+gcr_secret_exchange_get_secret (GcrSecretExchange *self,
+ gsize *secret_len)
{
g_return_val_if_fail (GCR_IS_SECRET_EXCHANGE (self), NULL);
@@ -362,58 +368,8 @@ gcr_secret_exchange_get_response (GcrSecretExchange *self,
return self->pv->secret;
}
-/* ----------------------------------------------------------------------------
- * RESPONDER SIDE
- */
-
static gpointer
-calculate_response_key (GKeyFile *input, GKeyFile *output)
-{
- gcry_mpi_t prime;
- gcry_mpi_t base;
- gcry_mpi_t pub;
- gcry_mpi_t priv;
- gcry_mpi_t peer;
- gpointer ikm;
- gsize n_ikm;
- gpointer key;
-
- peer = key_file_get_mpi (input, EXCHANGE_VERSION, "public");
- if (peer == NULL) {
- g_message ("secret-exchange: invalid or missing 'public' argument");
- return NULL;
- }
-
- if (!egg_dh_default_params (EXCHANGE_1_IKE_NAME, &prime, &base))
- g_return_val_if_reached (NULL);
-
- /* Generate our own public/priv, and then a key, send it back */
- if (!egg_dh_gen_pair (prime, base, 0, &pub, &priv))
- g_return_val_if_reached (NULL);
-
- /* Build up a key we can use */
- ikm = egg_dh_gen_secret (peer, priv, prime, &n_ikm);
- g_return_val_if_fail (ikm != NULL, NULL);
-
- key = egg_secure_alloc (EXCHANGE_1_KEY_LENGTH);
- if (!egg_hkdf_perform (EXCHANGE_1_HASH_ALGO, ikm, n_ikm, NULL, 0,
- NULL, 0, key, EXCHANGE_1_KEY_LENGTH))
- g_return_val_if_reached (NULL);
-
- key_file_set_mpi (output, EXCHANGE_VERSION, "public", pub);
-
- egg_secure_free (ikm);
- gcry_mpi_release (prime);
- gcry_mpi_release (base);
- gcry_mpi_release (peer);
- gcry_mpi_release (pub);
- gcry_mpi_release (priv);
-
- return key;
-}
-
-static gpointer
-calculate_response_iv (GKeyFile *input, GKeyFile *output)
+calculate_iv (GKeyFile *output)
{
gpointer iv;
@@ -425,29 +381,25 @@ calculate_response_iv (GKeyFile *input, GKeyFile *output)
}
static gboolean
-perform_aes_encrypt (GKeyFile *input, GKeyFile *output,
- gconstpointer secret, gsize n_secret)
+perform_aes_encrypt (GKeyFile *output,
+ gconstpointer key,
+ const gchar *secret,
+ gsize n_secret)
{
gcry_cipher_hd_t cih;
gcry_error_t gcry;
guchar* padded;
guchar* result;
- gpointer key;
gpointer iv;
gsize n_result;
gsize pos;
- key = calculate_response_key (input, output);
- if (key == NULL)
- return FALSE;
-
- iv = calculate_response_iv (input, output);
+ iv = calculate_iv (output);
g_return_val_if_fail (iv != NULL, FALSE);
gcry = gcry_cipher_open (&cih, EXCHANGE_1_CIPHER_ALGO, EXCHANGE_1_CIPHER_MODE, 0);
if (gcry != 0) {
g_warning ("couldn't create aes cipher context: %s", gcry_strerror (gcry));
- egg_secure_free (key);
g_free (iv);
return FALSE;
}
@@ -460,7 +412,6 @@ perform_aes_encrypt (GKeyFile *input, GKeyFile *output,
gcry = gcry_cipher_setiv (cih, iv, EXCHANGE_1_IV_LENGTH);
g_return_val_if_fail (gcry == 0, FALSE);
- egg_secure_free (key);
g_free (iv);
/* Pad the text properly */
@@ -479,45 +430,42 @@ perform_aes_encrypt (GKeyFile *input, GKeyFile *output,
egg_secure_clear (padded, n_result);
egg_secure_free (padded);
- key_file_set_base64 (output, EXCHANGE_VERSION, "value", result, n_result);
+ key_file_set_base64 (output, EXCHANGE_VERSION, "secret", result, n_result);
g_free (result);
return TRUE;
}
gchar *
-gcr_secret_exchange_respond (const gchar *request,
- const guchar *secret,
- gssize secret_len)
+gcr_secret_exchange_send (GcrSecretExchange *self,
+ const gchar *secret,
+ gssize secret_len)
{
- GKeyFile *input;
GKeyFile *output;
gchar *result;
- g_return_val_if_fail (request, NULL);
- g_return_val_if_fail (secret, NULL);
-
- if (secret_len < 0)
- secret_len = strlen ((gchar *)secret);
+ g_return_val_if_fail (GCR_IS_SECRET_EXCHANGE (self), NULL);
- /* Parse the input */
- input = g_key_file_new ();
- if (!g_key_file_load_from_data (input, request, strlen (request),
- G_KEY_FILE_NONE, NULL)) {
- g_key_file_free (input);
- g_message ("couldn't parse secret exchange request data");
+ if (self->pv->key == NULL) {
+ g_warning ("gcr_secret_exchange_receive() must be called "
+ "before calling this function");
return NULL;
}
output = g_key_file_new ();
+ key_file_set_mpi (output, EXCHANGE_VERSION, "public", self->pv->pub);
- if (perform_aes_encrypt (input, output, secret, secret_len)) {
- result = g_key_file_to_data (output, NULL, NULL);
- g_return_val_if_fail (result != NULL, NULL);
+ if (secret != NULL) {
+ if (secret_len < 0)
+ secret_len = strlen (secret);
+ if (!perform_aes_encrypt (output, self->pv->key, secret, secret_len)) {
+ g_key_file_free (output);
+ return NULL;
+ }
}
- g_key_file_free (input);
+ result = g_key_file_to_data (output, NULL, NULL);
+ g_return_val_if_fail (result != NULL, NULL);
g_key_file_free (output);
-
return result;
}
diff --git a/gcr/gcr-secret-exchange.h b/gcr/gcr-secret-exchange.h
index 8ec8264..5bd3ecf 100644
--- a/gcr/gcr-secret-exchange.h
+++ b/gcr/gcr-secret-exchange.h
@@ -31,11 +31,11 @@
G_BEGIN_DECLS
#define GCR_TYPE_SECRET_EXCHANGE (gcr_secret_exchange_get_type ())
-#define GCR_SECRET_EXCHANGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_COLLECTION, GcrSecretExchange))
-#define GCR_SECRET_EXCHANGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_COLLECTION, GcrSecretExchangeClass))
-#define GCR_IS_SECRET_EXCHANGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_COLLECTION))
-#define GCR_IS_SECRET_EXCHANGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_COLLECTION))
-#define GCR_SECRET_EXCHANGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_COLLECTION, GcrSecretExchangeClass))
+#define GCR_SECRET_EXCHANGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_SECRET_EXCHANGE, GcrSecretExchange))
+#define GCR_SECRET_EXCHANGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_SECRET_EXCHANGE, GcrSecretExchangeClass))
+#define GCR_IS_SECRET_EXCHANGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_SECRET_EXCHANGE))
+#define GCR_IS_SECRET_EXCHANGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_SECRET_EXCHANGE))
+#define GCR_SECRET_EXCHANGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_SECRET_EXCHANGE, GcrSecretExchangeClass))
typedef struct _GcrSecretExchange GcrSecretExchange;
typedef struct _GcrSecretExchangeClass GcrSecretExchangeClass;
@@ -58,20 +58,17 @@ GType gcr_secret_exchange_get_type (void);
GcrSecretExchange * gcr_secret_exchange_new (void);
-gchar * gcr_secret_exchange_request (GcrSecretExchange *self);
+gchar * gcr_secret_exchange_begin (GcrSecretExchange *self);
gboolean gcr_secret_exchange_receive (GcrSecretExchange *self,
- const gchar *response);
+ const gchar *exchange);
-const guchar * gcr_secret_exchange_get_response (GcrSecretExchange *self,
- gsize *secret_len);
-
-/* Responder side functions */
-
-gchar * gcr_secret_exchange_respond (const gchar *request,
- const guchar *secret,
+gchar * gcr_secret_exchange_send (GcrSecretExchange *self,
+ const gchar *secret,
gssize secret_len);
+const gchar * gcr_secret_exchange_get_secret (GcrSecretExchange *self,
+ gsize *secret_len);
G_END_DECLS
diff --git a/gcr/tests/Makefile.am b/gcr/tests/Makefile.am
index 018f0bb..5872ff9 100644
--- a/gcr/tests/Makefile.am
+++ b/gcr/tests/Makefile.am
@@ -21,6 +21,7 @@ LDADD = \
TEST_PROGS = \
test-util \
+ test-secret-exchange \
test-simple-certificate \
test-certificate \
test-certificate-chain \
diff --git a/gcr/tests/test-secret-exchange.c b/gcr/tests/test-secret-exchange.c
new file mode 100644
index 0000000..48581fe
--- /dev/null
+++ b/gcr/tests/test-secret-exchange.c
@@ -0,0 +1,162 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ 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 "gcr/gcr.h"
+
+#include <glib.h>
+
+#include <errno.h>
+
+typedef struct {
+ GcrSecretExchange *caller;
+ GcrSecretExchange *callee;
+} Test;
+
+static void
+setup (Test *test, gconstpointer unused)
+{
+ test->caller = gcr_secret_exchange_new ();
+ g_assert (GCR_IS_SECRET_EXCHANGE (test->caller));
+ test->callee = gcr_secret_exchange_new ();
+ g_assert (GCR_IS_SECRET_EXCHANGE (test->callee));
+}
+
+static void
+teardown (Test *test,
+ gconstpointer unused)
+{
+ g_object_unref (test->caller);
+ g_assert (!GCR_IS_SECRET_EXCHANGE (test->caller));
+ g_object_unref (test->callee);
+ g_assert (!GCR_IS_SECRET_EXCHANGE (test->callee));
+}
+
+static void
+test_perform_exchange (Test *test,
+ gconstpointer unused)
+{
+ gchar *exchange;
+
+ exchange = gcr_secret_exchange_begin (test->caller);
+ g_assert (exchange);
+
+ if (!gcr_secret_exchange_receive (test->callee, exchange))
+ g_assert_not_reached ();
+
+ g_free (exchange);
+
+ exchange = gcr_secret_exchange_send (test->callee, "the secret", -1);
+ g_assert (exchange);
+
+ if (!gcr_secret_exchange_receive (test->caller, exchange))
+ g_assert_not_reached ();
+
+ g_assert_cmpstr (gcr_secret_exchange_get_secret (test->caller, NULL), ==, "the secret");
+
+ g_free (exchange);
+}
+
+static void
+test_perform_reverse (Test *test,
+ gconstpointer unused)
+{
+ gchar *exchange;
+
+ exchange = gcr_secret_exchange_begin (test->caller);
+ g_assert (exchange);
+
+ if (!gcr_secret_exchange_receive (test->callee, exchange))
+ g_assert_not_reached ();
+
+ g_free (exchange);
+
+ exchange = gcr_secret_exchange_send (test->callee, NULL, -1);
+ g_assert (exchange);
+
+ if (!gcr_secret_exchange_receive (test->caller, exchange))
+ g_assert_not_reached ();
+
+ g_free (exchange);
+
+ g_assert (gcr_secret_exchange_get_secret (test->caller, NULL) == NULL);
+
+ exchange = gcr_secret_exchange_send (test->caller, "reverse secret", -1);
+ g_assert (exchange);
+
+ if (!gcr_secret_exchange_receive (test->callee, exchange))
+ g_assert_not_reached ();
+
+ g_free (exchange);
+
+ g_assert_cmpstr (gcr_secret_exchange_get_secret (test->callee, NULL), ==, "reverse secret");
+}
+
+static void
+test_perform_multiple (Test *test,
+ gconstpointer unused)
+{
+ gchar *exchange;
+
+ exchange = gcr_secret_exchange_begin (test->caller);
+ g_assert (exchange);
+
+ if (!gcr_secret_exchange_receive (test->callee, exchange))
+ g_assert_not_reached ();
+
+ g_free (exchange);
+
+ exchange = gcr_secret_exchange_send (test->callee, "first secret", -1);
+ g_assert (exchange);
+
+ if (!gcr_secret_exchange_receive (test->caller, exchange))
+ g_assert_not_reached ();
+
+ g_free (exchange);
+
+ g_assert_cmpstr (gcr_secret_exchange_get_secret (test->caller, NULL), ==, "first secret");
+
+ exchange = gcr_secret_exchange_send (test->callee, "second secret", -1);
+ g_assert (exchange);
+
+ if (!gcr_secret_exchange_receive (test->caller, exchange))
+ g_assert_not_reached ();
+
+ g_free (exchange);
+
+ g_assert_cmpstr (gcr_secret_exchange_get_secret (test->caller, NULL), ==, "second secret");
+}
+
+int
+main (int argc, char **argv)
+{
+ g_type_init ();
+ g_test_init (&argc, &argv, NULL);
+ g_set_prgname ("test-secret-exchange");
+
+ g_test_add ("/gcr/secret-exchange/perform-exchange", Test, NULL, setup, test_perform_exchange, teardown);
+ g_test_add ("/gcr/secret-exchange/perform-reverse", Test, NULL, setup, test_perform_reverse, teardown);
+ g_test_add ("/gcr/secret-exchange/perform-multiple", Test, NULL, setup, test_perform_multiple, teardown);
+
+ return g_test_run ();
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]