summaryrefslogtreecommitdiff
path: root/src/exchangedb
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-05-06 19:22:39 +0200
committerChristian Grothoff <christian@grothoff.org>2016-05-06 19:22:39 +0200
commit187fa67f3c8791bec65f075d285081460e5f2170 (patch)
tree56c2ec5ea078820899e31260ff37db310a832900 /src/exchangedb
parent3526c44a38195aaea2ab48a220728df175ab9429 (diff)
downloadexchange-187fa67f3c8791bec65f075d285081460e5f2170.tar.gz
exchange-187fa67f3c8791bec65f075d285081460e5f2170.tar.bz2
exchange-187fa67f3c8791bec65f075d285081460e5f2170.zip
refactoring exchangedb tests to improve coverage
Diffstat (limited to 'src/exchangedb')
-rw-r--r--src/exchangedb/Makefile.am24
-rw-r--r--src/exchangedb/exchangedb_auditorkeys.c283
-rw-r--r--src/exchangedb/exchangedb_denomkeys.c269
-rw-r--r--src/exchangedb/exchangedb_keyio.c666
-rw-r--r--src/exchangedb/exchangedb_signkeys.c175
-rw-r--r--src/exchangedb/test_exchangedb_denomkeys.c (renamed from src/exchangedb/test_exchangedb_keyio.c)26
6 files changed, 765 insertions, 678 deletions
diff --git a/src/exchangedb/Makefile.am b/src/exchangedb/Makefile.am
index fc87feea1..7cc3a4da8 100644
--- a/src/exchangedb/Makefile.am
+++ b/src/exchangedb/Makefile.am
@@ -42,7 +42,9 @@ lib_LTLIBRARIES = \
libtalerexchangedb.la
libtalerexchangedb_la_SOURCES = \
- exchangedb_keyio.c \
+ exchangedb_auditorkeys.c \
+ exchangedb_denomkeys.c \
+ exchangedb_signkeys.c \
exchangedb_plugin.c
libtalerexchangedb_la_LIBADD = \
@@ -56,7 +58,8 @@ libtalerexchangedb_la_LDFLAGS = \
check_PROGRAMS = \
- test-exchangedb-keyio \
+ test-exchangedb-denomkeys \
+ test-exchangedb-signkeys \
test-exchangedb-postgres \
test-perf-taler-exchangedb \
perf-exchangedb
@@ -64,12 +67,21 @@ check_PROGRAMS = \
AM_TESTS_ENVIRONMENT=export TALER_PREFIX=$${TALER_PREFIX:-@libdir@};export PATH=$${TALER_PREFIX:-@prefix@}/bin:$$PATH;
TESTS = \
test-exchangedb-postgres \
+ test-exchangedb-signkeys \
test-perf-taler-exchangedb \
- test-exchangedb-keyio
+ test-exchangedb-denomkeys
-test_exchangedb_keyio_SOURCES = \
- test_exchangedb_keyio.c
-test_exchangedb_keyio_LDADD = \
+test_exchangedb_denomkeys_SOURCES = \
+ test_exchangedb_denomkeys.c
+test_exchangedb_denomkeys_LDADD = \
+ libtalerexchangedb.la \
+ $(top_srcdir)/src/util/libtalerutil.la \
+ $(top_srcdir)/src/pq/libtalerpq.la \
+ -lgnunetutil
+
+test_exchangedb_signkeys_SOURCES = \
+ test_exchangedb_signkeys.c
+test_exchangedb_signkeys_LDADD = \
libtalerexchangedb.la \
$(top_srcdir)/src/util/libtalerutil.la \
$(top_srcdir)/src/pq/libtalerpq.la \
diff --git a/src/exchangedb/exchangedb_auditorkeys.c b/src/exchangedb/exchangedb_auditorkeys.c
new file mode 100644
index 000000000..a27ff86d5
--- /dev/null
+++ b/src/exchangedb/exchangedb_auditorkeys.c
@@ -0,0 +1,283 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2014, 2015, 2016 Inria & GNUnet e.V.
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file exchangedb/exchangedb_auditorkeys.c
+ * @brief I/O operations for the Exchange's auditor data
+ * @author Florian Dold
+ * @author Benedikt Mueller
+ * @author Sree Harsha Totakura
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "taler_exchangedb_lib.h"
+
+
+/**
+ * Closure for #auditor_iter() and
+ */
+struct AuditorIterateContext
+{
+
+ /**
+ * Function to call with the information for each auditor.
+ */
+ TALER_EXCHANGEDB_AuditorIterator it;
+
+ /**
+ * Closure for @e it.
+ */
+ void *it_cls;
+};
+
+
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * Header of a file with auditing information.
+ */
+struct AuditorFileHeaderP
+{
+
+ /**
+ * Public key of the auditor.
+ */
+ struct TALER_AuditorPublicKeyP apub;
+
+ /**
+ * Master public key of the exchange the auditor is signing
+ * information for.
+ */
+ struct TALER_MasterPublicKeyP mpub;
+
+ /**
+ * Number of signatures and DKI entries in this file.
+ */
+ uint32_t dki_len;
+
+};
+GNUNET_NETWORK_STRUCT_END
+
+
+/**
+ * Load the auditor signature and the information signed by the
+ * auditor and call the callback in @a cls with the information.
+ *
+ * @param cls the `struct AuditorIterateContext *`
+ * @param filename name of a file that should contain
+ * a denomination key
+ * @return #GNUNET_OK to continue to iterate
+ * #GNUNET_NO to abort iteration with success
+ * #GNUNET_SYSERR to abort iteration with failure
+ */
+static int
+auditor_iter (void *cls,
+ const char *filename)
+{
+ struct AuditorIterateContext *aic = cls;
+ uint64_t size;
+ struct AuditorFileHeaderP *af;
+ const struct TALER_AuditorSignatureP *sigs;
+ const struct TALER_DenominationKeyValidityPS *dki;
+ const char *auditor_url;
+ unsigned int dki_len;
+ size_t url_len;
+ int ret;
+
+ if (GNUNET_OK != GNUNET_DISK_file_size (filename,
+ &size,
+ GNUNET_YES,
+ GNUNET_YES))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Skipping inaccessable auditor information file `%s'\n",
+ filename);
+ return GNUNET_SYSERR;
+ }
+ if (size < sizeof (struct AuditorFileHeaderP))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ af = GNUNET_malloc (size);
+ if (size !=
+ GNUNET_DISK_fn_read (filename,
+ af,
+ size))
+ {
+ GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
+ "read",
+ filename);
+ GNUNET_free (af);
+ return GNUNET_SYSERR;
+ }
+ dki_len = ntohl (af->dki_len);
+ if (0 == dki_len)
+ {
+ GNUNET_break_op (0);
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "No signed keys in %s\n",
+ filename);
+ GNUNET_free (af);
+ return GNUNET_SYSERR;
+ }
+ if ( (size - sizeof (struct AuditorFileHeaderP)) / dki_len <
+ (sizeof (struct TALER_DenominationKeyValidityPS) +
+ sizeof (struct TALER_AuditorSignatureP)) )
+ {
+ GNUNET_break_op (0);
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Malformed key file %s\n",
+ filename);
+ GNUNET_free (af);
+ return GNUNET_SYSERR;
+ }
+ url_len = size
+ - sizeof (struct AuditorFileHeaderP)
+ - dki_len * (sizeof (struct TALER_DenominationKeyValidityPS) +
+ sizeof (struct TALER_AuditorSignatureP));
+ sigs = (const struct TALER_AuditorSignatureP *) &af[1];
+ dki = (const struct TALER_DenominationKeyValidityPS *) &sigs[dki_len];
+ auditor_url = (const char *) &dki[dki_len];
+ if ( (0 == url_len) ||
+ ('\0' != auditor_url[url_len - 1]) )
+ {
+ GNUNET_break_op (0);
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Malformed key file %s\n",
+ filename);
+ GNUNET_free (af);
+ return GNUNET_SYSERR;
+ }
+ ret = aic->it (aic->it_cls,
+ &af->apub,
+ auditor_url,
+ &af->mpub,
+ dki_len,
+ sigs,
+ dki);
+ GNUNET_free (af);
+ return ret;
+}
+
+
+/**
+ * Call @a it with information for each auditor found in the @a exchange_base_dir.
+ *
+ * @param cfg configuration to use
+ * @param it function to call with auditor information
+ * @param it_cls closure for @a it
+ * @return -1 on error, 0 if no files were found, otherwise
+ * a positive number (however, even with a positive
+ * number it is possible that @a it was never called
+ * as maybe none of the files were well-formed)
+ */
+int
+TALER_EXCHANGEDB_auditor_iterate (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ TALER_EXCHANGEDB_AuditorIterator it,
+ void *it_cls)
+{
+ struct AuditorIterateContext aic;
+ int ret;
+ char *auditor_base_dir;
+
+ if (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_filename (cfg,
+ "exchangedb",
+ "AUDITOR_BASE_DIR",
+ &auditor_base_dir))
+ return -1;
+ aic.it = it;
+ aic.it_cls = it_cls;
+ ret = GNUNET_DISK_directory_scan (auditor_base_dir,
+ &auditor_iter,
+ &aic);
+ GNUNET_free (auditor_base_dir);
+ return ret;
+}
+
+
+/**
+ * Write auditor information to the given file.
+ *
+ * @param filename the file where to write the auditor information to
+ * @param apub the auditor's public key
+ * @param auditor_url the URL of the auditor
+ * @param asigs the auditor's signatures, array of length @a dki_len
+ * @param mpub the exchange's public key (as expected by the auditor)
+ * @param dki_len length of @a dki
+ * @param dki array of denomination coin data signed by the auditor
+ * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure.
+ */
+int
+TALER_EXCHANGEDB_auditor_write (const char *filename,
+ const struct TALER_AuditorPublicKeyP *apub,
+ const char *auditor_url,
+ const struct TALER_AuditorSignatureP *asigs,
+ const struct TALER_MasterPublicKeyP *mpub,
+ unsigned int dki_len,
+ const struct TALER_DenominationKeyValidityPS *dki)
+{
+ struct AuditorFileHeaderP af;
+ struct GNUNET_DISK_FileHandle *fh;
+ ssize_t wrote;
+ size_t wsize;
+ int ret;
+ int eno;
+
+ af.apub = *apub;
+ af.mpub = *mpub;
+ af.dki_len = htonl ((uint32_t) dki_len);
+ ret = GNUNET_SYSERR;
+ if (NULL == (fh = GNUNET_DISK_file_open
+ (filename,
+ GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_TRUNCATE,
+ GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE)))
+ goto cleanup;
+ wsize = sizeof (struct AuditorFileHeaderP);
+ if (GNUNET_SYSERR == (wrote = GNUNET_DISK_file_write (fh,
+ &af,
+ wsize)))
+ goto cleanup;
+ if (wrote != wsize)
+ goto cleanup;
+ wsize = dki_len * sizeof (struct TALER_AuditorSignatureP);
+ if (wsize ==
+ GNUNET_DISK_file_write (fh,
+ asigs,
+ wsize))
+ ret = GNUNET_OK;
+ wsize = dki_len * sizeof (struct TALER_DenominationKeyValidityPS);
+ if (wsize ==
+ GNUNET_DISK_file_write (fh,
+ dki,
+ wsize))
+ ret = GNUNET_OK;
+ wsize = strlen (auditor_url) + 1;
+ if (wsize ==
+ GNUNET_DISK_file_write (fh,
+ auditor_url,
+ wsize))
+ ret = GNUNET_OK;
+ cleanup:
+ eno = errno;
+ if (NULL != fh)
+ (void) GNUNET_DISK_file_close (fh);
+ errno = eno;
+ return ret;
+}
+
+
+/* end of exchangedb_keyio.c */
diff --git a/src/exchangedb/exchangedb_denomkeys.c b/src/exchangedb/exchangedb_denomkeys.c
new file mode 100644
index 000000000..dea312dd2
--- /dev/null
+++ b/src/exchangedb/exchangedb_denomkeys.c
@@ -0,0 +1,269 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2014, 2015, 2016 Inria & GNUnet e.V.
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file exchangedb/exchangedb_denomkeys.c
+ * @brief I/O operations for the Exchange's denomination private keys
+ * @author Florian Dold
+ * @author Benedikt Mueller
+ * @author Sree Harsha Totakura
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "taler_exchangedb_lib.h"
+
+
+/**
+ * Import a denomination key from the given file.
+ *
+ * @param filename the file to import the key from
+ * @param[out] dki set to the imported denomination key
+ * @return #GNUNET_OK upon success;
+ * #GNUNET_SYSERR upon failure
+ */
+int
+TALER_EXCHANGEDB_denomination_key_read (const char *filename,
+ struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki)
+{
+ uint64_t size;
+ size_t offset;
+ void *data;
+ struct GNUNET_CRYPTO_RsaPrivateKey *priv;
+
+ if (GNUNET_OK != GNUNET_DISK_file_size (filename,
+ &size,
+ GNUNET_YES,
+ GNUNET_YES))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Skipping inaccessable denomination key file `%s'\n",
+ filename);
+ return GNUNET_SYSERR;
+ }
+ offset = sizeof (struct TALER_EXCHANGEDB_DenominationKeyInformationP);
+ if (size <= offset)
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ data = GNUNET_malloc (size);
+ if (size !=
+ GNUNET_DISK_fn_read (filename,
+ data,
+ size))
+ {
+ GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
+ "read",
+ filename);
+ GNUNET_free (data);
+ return GNUNET_SYSERR;
+ }
+ if (NULL ==
+ (priv = GNUNET_CRYPTO_rsa_private_key_decode (data + offset,
+ size - offset)))
+ {
+ GNUNET_free (data);
+ return GNUNET_SYSERR;
+ }
+ GNUNET_assert (NULL == dki->denom_priv.rsa_private_key);
+ dki->denom_priv.rsa_private_key = priv;
+ dki->denom_pub.rsa_public_key
+ = GNUNET_CRYPTO_rsa_private_key_get_public (priv);
+ memcpy (&dki->issue,
+ data,
+ offset);
+ GNUNET_free (data);
+ return GNUNET_OK;
+}
+
+
+/**
+ * Exports a denomination key to the given file.
+ *
+ * @param filename the file where to write the denomination key
+ * @param dki the denomination key
+ * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure.
+ */
+int
+TALER_EXCHANGEDB_denomination_key_write (const char *filename,
+ const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki)
+{
+ char *priv_enc;
+ size_t priv_enc_size;
+ struct GNUNET_DISK_FileHandle *fh;
+ ssize_t wrote;
+ size_t wsize;
+ int ret;
+
+ fh = NULL;
+ priv_enc_size
+ = GNUNET_CRYPTO_rsa_private_key_encode (dki->denom_priv.rsa_private_key,
+ &priv_enc);
+ ret = GNUNET_SYSERR;
+ if (GNUNET_OK !=
+ GNUNET_DISK_directory_create_for_file (filename))
+ return GNUNET_SYSERR;
+ if (NULL == (fh = GNUNET_DISK_file_open
+ (filename,
+ GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_TRUNCATE,
+ GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE)))
+ goto cleanup;
+ wsize = sizeof (struct TALER_EXCHANGEDB_DenominationKeyInformationP);
+ if (GNUNET_SYSERR == (wrote = GNUNET_DISK_file_write (fh,
+ &dki->issue,
+ wsize)))
+ goto cleanup;
+ if (wrote != wsize)
+ goto cleanup;
+ if (GNUNET_SYSERR ==
+ (wrote = GNUNET_DISK_file_write (fh,
+ priv_enc,
+ priv_enc_size)))
+ goto cleanup;
+ if (wrote != priv_enc_size)
+ goto cleanup;
+ ret = GNUNET_OK;
+ cleanup:
+ GNUNET_free_non_null (priv_enc);
+ if (NULL != fh)
+ (void) GNUNET_DISK_file_close (fh);
+ return ret;
+}
+
+
+/**
+ * Closure for #denomkeys_iterate_keydir_iter() and
+ * #denomkeys_iterate_topdir_iter().
+ */
+struct DenomkeysIterateContext
+{
+
+ /**
+ * Set to the name of the directory below the top-level directory
+ * during the call to #denomkeys_iterate_keydir_iter().
+ */
+ const char *alias;
+
+ /**
+ * Function to call on each denomination key.
+ */
+ TALER_EXCHANGEDB_DenominationKeyIterator it;
+
+ /**
+ * Closure for @e it.
+ */
+ void *it_cls;
+};
+
+
+/**
+ * Decode the denomination key in the given file @a filename and call
+ * the callback in @a cls with the information.
+ *
+ * @param cls the `struct DenomkeysIterateContext *`
+ * @param filename name of a file that should contain
+ * a denomination key
+ * @return #GNUNET_OK to continue to iterate
+ * #GNUNET_NO to abort iteration with success
+ * #GNUNET_SYSERR to abort iteration with failure
+ */
+static int
+denomkeys_iterate_keydir_iter (void *cls,
+ const char *filename)
+{
+ struct DenomkeysIterateContext *dic = cls;
+ struct TALER_EXCHANGEDB_DenominationKeyIssueInformation issue;
+ int ret;
+
+ memset (&issue, 0, sizeof (issue));
+ if (GNUNET_OK !=
+ TALER_EXCHANGEDB_denomination_key_read (filename,
+ &issue))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Invalid denomkey file: '%s'\n",
+ filename);
+ return GNUNET_OK;
+ }
+ ret = dic->it (dic->it_cls,
+ dic->alias,
+ &issue);
+ GNUNET_CRYPTO_rsa_private_key_free (issue.denom_priv.rsa_private_key);
+ GNUNET_CRYPTO_rsa_public_key_free (issue.denom_pub.rsa_public_key);
+ return ret;
+}
+
+
+/**
+ * Function called on each subdirectory in the #TALER_EXCHANGEDB_DIR_DENOMINATION_KEYS. Will
+ * call the #denomkeys_iterate_keydir_iter() on each file in the
+ * subdirectory.
+ *
+ * @param cls the `struct DenomkeysIterateContext *`
+ * @param filename name of the subdirectory to scan
+ * @return #GNUNET_OK on success,
+ * #GNUNET_SYSERR if we need to abort
+ */
+static int
+denomkeys_iterate_topdir_iter (void *cls,
+ const char *filename)
+{
+ struct DenomkeysIterateContext *dic = cls;
+
+ dic->alias = GNUNET_STRINGS_get_short_name (filename);
+ if (0 > GNUNET_DISK_directory_scan (filename,
+ &denomkeys_iterate_keydir_iter,
+ dic))
+ return GNUNET_SYSERR;
+ return GNUNET_OK;
+}
+
+
+/**
+ * Call @a it for each denomination key found in the @a exchange_base_dir.
+ *
+ * @param exchange_base_dir base directory for the exchange,
+ * the signing keys must be in the #TALER_EXCHANGEDB_DIR_DENOMINATION_KEYS
+ * subdirectory
+ * @param it function to call on each denomination key found
+ * @param it_cls closure for @a it
+ * @return -1 on error, 0 if no files were found, otherwise
+ * a positive number (however, even with a positive
+ * number it is possible that @a it was never called
+ * as maybe none of the files were well-formed)
+ */
+int
+TALER_EXCHANGEDB_denomination_keys_iterate (const char *exchange_base_dir,
+ TALER_EXCHANGEDB_DenominationKeyIterator it,
+ void *it_cls)
+{
+ char *dir;
+ struct DenomkeysIterateContext dic;
+ int ret;
+
+ GNUNET_asprintf (&dir,
+ "%s" DIR_SEPARATOR_STR TALER_EXCHANGEDB_DIR_DENOMINATION_KEYS,
+ exchange_base_dir);
+ dic.it = it;
+ dic.it_cls = it_cls;
+ ret = GNUNET_DISK_directory_scan (dir,
+ &denomkeys_iterate_topdir_iter,
+ &dic);
+ GNUNET_free (dir);
+ return ret;
+}
+
+
+/* end of exchangedb_denomkeys.c */
diff --git a/src/exchangedb/exchangedb_keyio.c b/src/exchangedb/exchangedb_keyio.c
deleted file mode 100644
index 773fc9284..000000000
--- a/src/exchangedb/exchangedb_keyio.c
+++ /dev/null
@@ -1,666 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014, 2015, 2016 Inria & GNUnet e.V.
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
-*/
-/**
- * @file exchangedb/exchangedb_keyio.c
- * @brief I/O operations for the Exchange's private keys
- * @author Florian Dold
- * @author Benedikt Mueller
- * @author Sree Harsha Totakura
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include "taler_exchangedb_lib.h"
-
-
-/**
- * Closure for the #signkeys_iterate_dir_iter().
- */
-struct SignkeysIterateContext
-{
-
- /**
- * Function to call on each signing key.
- */
- TALER_EXCHANGEDB_SigningKeyIterator it;
-
- /**
- * Closure for @e it.
- */
- void *it_cls;
-};
-
-
-/**
- * Function called on each file in the directory with our signing
- * keys. Parses the file and calls the iterator from @a cls.
- *
- * @param cls the `struct SignkeysIterateContext *`
- * @param filename name of the file to parse
- * @return #GNUNET_OK to continue,
- * #GNUNET_NO to stop iteration without error,
- * #GNUNET_SYSERR to stop iteration with error
- */
-static int
-signkeys_iterate_dir_iter (void *cls,
- const char *filename)
-{
- struct SignkeysIterateContext *skc = cls;
- ssize_t nread;
- struct TALER_EXCHANGEDB_PrivateSigningKeyInformationP issue;
-
- nread = GNUNET_DISK_fn_read (filename,
- &issue,
- sizeof (struct TALER_EXCHANGEDB_PrivateSigningKeyInformationP));
- if (nread != sizeof (struct TALER_EXCHANGEDB_PrivateSigningKeyInformationP))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Invalid signkey file `%s': wrong size (%d, expected %u)\n",
- filename,
- (int) nread,
- (unsigned int) sizeof (struct TALER_EXCHANGEDB_PrivateSigningKeyInformationP));
- return GNUNET_OK;
- }
- return skc->it (skc->it_cls,
- filename,
- &issue);
-}
-
-
-/**
- * Call @a it for each signing key found in the @a exchange_base_dir.
- *
- * @param exchange_base_dir base directory for the exchange,
- * the signing keys must be in the #TALER_EXCHANGEDB_DIR_SIGNING_KEYS
- * subdirectory
- * @param it function to call on each signing key
- * @param it_cls closure for @a it
- * @return number of files found (may not match
- * number of keys given to @a it as malformed
- * files are simply skipped), -1 on error
- */
-int
-TALER_EXCHANGEDB_signing_keys_iterate (const char *exchange_base_dir,
- TALER_EXCHANGEDB_SigningKeyIterator it,
- void *it_cls)
-{
- char *signkey_dir;
- struct SignkeysIterateContext skc;
- int ret;
-
- GNUNET_asprintf (&signkey_dir,
- "%s" DIR_SEPARATOR_STR TALER_EXCHANGEDB_DIR_SIGNING_KEYS,
- exchange_base_dir);
- skc.it = it;
- skc.it_cls = it_cls;
- ret = GNUNET_DISK_directory_scan (signkey_dir,
- &signkeys_iterate_dir_iter,
- &skc);
- GNUNET_free (signkey_dir);
- return ret;
-}
-
-
-/**
- * Obtain the name of the directory we use to store signing
- * keys created at time @a start.
- *
- * @param start time at which we create the signing key
- * @return name of the directory we should use, basically "$EXCHANGEDIR/$TIME/";
- * (valid until next call to this function)
- */
-static char *
-get_signkey_file (const char *exchange_directory,
- struct GNUNET_TIME_Absolute start)
-{
- char *dir;
-
- GNUNET_asprintf (&dir,
- "%s" DIR_SEPARATOR_STR TALER_EXCHANGEDB_DIR_SIGNING_KEYS DIR_SEPARATOR_STR "%llu",
- exchange_directory,
- (unsigned long long) start.abs_value_us);
- return dir;
-}
-
-
-/**
- * Exports a signing key to the given file.
- *
- * @param exchange_base_dir base directory for the keys
- * @param start start time of the validity for the key
- * @param ski the signing key
- * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure.
- */
-int
-TALER_EXCHANGEDB_signing_key_write (const char *exchange_base_dir,
- struct GNUNET_TIME_Absolute start,
- const struct TALER_EXCHANGEDB_PrivateSigningKeyInformationP *ski)
-{
- char *skf;
- ssize_t nwrite;
-
- skf = get_signkey_file (exchange_base_dir,
- start);
- nwrite = GNUNET_DISK_fn_write (skf,
- ski,
- sizeof (struct TALER_EXCHANGEDB_PrivateSigningKeyInformationP),
- GNUNET_DISK_PERM_USER_WRITE | GNUNET_DISK_PERM_USER_READ);
- if (sizeof (struct TALER_EXCHANGEDB_PrivateSigningKeyInformationP) != nwrite)
- {
- GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
- "write",
- skf);
- GNUNET_free (skf);
- return GNUNET_SYSERR;
- }
- GNUNET_free (skf);
- return GNUNET_OK;
-}
-
-
-/**
- * Import a denomination key from the given file.
- *
- * @param filename the file to import the key from
- * @param[out] dki set to the imported denomination key
- * @return #GNUNET_OK upon success;
- * #GNUNET_SYSERR upon failure
- */
-int
-TALER_EXCHANGEDB_denomination_key_read (const char *filename,
- struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki)
-{
- uint64_t size;
- size_t offset;
- void *data;
- struct GNUNET_CRYPTO_RsaPrivateKey *priv;
-
- if (GNUNET_OK != GNUNET_DISK_file_size (filename,
- &size,
- GNUNET_YES,
- GNUNET_YES))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Skipping inaccessable denomination key file `%s'\n",
- filename);
- return GNUNET_SYSERR;
- }
- offset = sizeof (struct TALER_EXCHANGEDB_DenominationKeyInformationP);
- if (size <= offset)
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- data = GNUNET_malloc (size);
- if (size !=
- GNUNET_DISK_fn_read (filename,
- data,
- size))
- {
- GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
- "read",
- filename);
- GNUNET_free (data);
- return GNUNET_SYSERR;
- }
- if (NULL ==
- (priv = GNUNET_CRYPTO_rsa_private_key_decode (data + offset,
- size - offset)))
- {
- GNUNET_free (data);
- return GNUNET_SYSERR;
- }
- GNUNET_assert (NULL == dki->denom_priv.rsa_private_key);
- dki->denom_priv.rsa_private_key = priv;
- dki->denom_pub.rsa_public_key
- = GNUNET_CRYPTO_rsa_private_key_get_public (priv);
- memcpy (&dki->issue,
- data,
- offset);
- GNUNET_free (data);
- return GNUNET_OK;
-}
-
-
-/**
- * Exports a denomination key to the given file.
- *
- * @param filename the file where to write the denomination key
- * @param dki the denomination key
- * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure.
- */
-int
-TALER_EXCHANGEDB_denomination_key_write (const char *filename,
- const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki)
-{
- char *priv_enc;
- size_t priv_enc_size;
- struct GNUNET_DISK_FileHandle *fh;
- ssize_t wrote;
- size_t wsize;
- int ret;
-
- fh = NULL;
- priv_enc_size
- = GNUNET_CRYPTO_rsa_private_key_encode (dki->denom_priv.rsa_private_key,
- &priv_enc);
- ret = GNUNET_SYSERR;
- if (NULL == (fh = GNUNET_DISK_file_open
- (filename,
- GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_TRUNCATE,
- GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE)))
- goto cleanup;
- wsize = sizeof (struct TALER_EXCHANGEDB_DenominationKeyInformationP);
- if (GNUNET_SYSERR == (wrote = GNUNET_DISK_file_write (fh,
- &dki->issue,
- wsize)))
- goto cleanup;
- if (wrote != wsize)
- goto cleanup;
- if (GNUNET_SYSERR ==
- (wrote = GNUNET_DISK_file_write (fh,
- priv_enc,
- priv_enc_size)))
- goto cleanup;
- if (wrote != priv_enc_size)
- goto cleanup;
- ret = GNUNET_OK;
- cleanup:
- GNUNET_free_non_null (priv_enc);
- if (NULL != fh)
- (void) GNUNET_DISK_file_close (fh);
- return ret;
-}
-
-
-/**
- * Closure for #denomkeys_iterate_keydir_iter() and
- * #denomkeys_iterate_topdir_iter().
- */
-struct DenomkeysIterateContext
-{
-
- /**
- * Set to the name of the directory below the top-level directory
- * during the call to #denomkeys_iterate_keydir_iter().
- */
- const char *alias;
-
- /**
- * Function to call on each denomination key.
- */
- TALER_EXCHANGEDB_DenominationKeyIterator it;
-
- /**
- * Closure for @e it.
- */
- void *it_cls;
-};
-
-
-/**
- * Decode the denomination key in the given file @a filename and call
- * the callback in @a cls with the information.
- *
- * @param cls the `struct DenomkeysIterateContext *`
- * @param filename name of a file that should contain
- * a denomination key
- * @return #GNUNET_OK to continue to iterate
- * #GNUNET_NO to abort iteration with success
- * #GNUNET_SYSERR to abort iteration with failure
- */
-static int
-denomkeys_iterate_keydir_iter (void *cls,
- const char *filename)
-{
- struct DenomkeysIterateContext *dic = cls;
- struct TALER_EXCHANGEDB_DenominationKeyIssueInformation issue;
- int ret;
-
- memset (&issue, 0, sizeof (issue));
- if (GNUNET_OK !=
- TALER_EXCHANGEDB_denomination_key_read (filename,
- &issue))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Invalid denomkey file: '%s'\n",
- filename);
- return GNUNET_OK;
- }
- ret = dic->it (dic->it_cls,
- dic->alias,
- &issue);
- GNUNET_CRYPTO_rsa_private_key_free (issue.denom_priv.rsa_private_key);
- GNUNET_CRYPTO_rsa_public_key_free (issue.denom_pub.rsa_public_key);
- return ret;
-}
-
-
-/**
- * Function called on each subdirectory in the #TALER_EXCHANGEDB_DIR_DENOMINATION_KEYS. Will
- * call the #denomkeys_iterate_keydir_iter() on each file in the
- * subdirectory.
- *
- * @param cls the `struct DenomkeysIterateContext *`
- * @param filename name of the subdirectory to scan
- * @return #GNUNET_OK on success,
- * #GNUNET_SYSERR if we need to abort
- */
-static int
-denomkeys_iterate_topdir_iter (void *cls,
- const char *filename)
-{
- struct DenomkeysIterateContext *dic = cls;
-
- dic->alias = GNUNET_STRINGS_get_short_name (filename);
- if (0 > GNUNET_DISK_directory_scan (filename,
- &denomkeys_iterate_keydir_iter,
- dic))
- return GNUNET_SYSERR;
- return GNUNET_OK;
-}
-
-
-/**
- * Call @a it for each denomination key found in the @a exchange_base_dir.
- *
- * @param exchange_base_dir base directory for the exchange,
- * the signing keys must be in the #TALER_EXCHANGEDB_DIR_DENOMINATION_KEYS
- * subdirectory
- * @param it function to call on each denomination key found
- * @param it_cls closure for @a it
- * @return -1 on error, 0 if no files were found, otherwise
- * a positive number (however, even with a positive
- * number it is possible that @a it was never called
- * as maybe none of the files were well-formed)
- */
-int
-TALER_EXCHANGEDB_denomination_keys_iterate (const char *exchange_base_dir,
- TALER_EXCHANGEDB_DenominationKeyIterator it,
- void *it_cls)
-{
- char *dir;
- struct DenomkeysIterateContext dic;
- int ret;
-
- GNUNET_asprintf (&dir,
- "%s" DIR_SEPARATOR_STR TALER_EXCHANGEDB_DIR_DENOMINATION_KEYS,
- exchange_base_dir);
- dic.it = it;
- dic.it_cls = it_cls;
- ret = GNUNET_DISK_directory_scan (dir,
- &denomkeys_iterate_topdir_iter,
- &dic);
- GNUNET_free (dir);
- return ret;
-}
-
-
-/**
- * Closure for #auditor_iter() and
- */
-struct AuditorIterateContext
-{
-
- /**
- * Function to call with the information for each auditor.
- */
- TALER_EXCHANGEDB_AuditorIterator it;
-
- /**
- * Closure for @e it.
- */
- void *it_cls;
-};
-
-
-GNUNET_NETWORK_STRUCT_BEGIN
-
-/**
- * Header of a file with auditing information.
- */
-struct AuditorFileHeaderP
-{
-
- /**
- * Public key of the auditor.
- */
- struct TALER_AuditorPublicKeyP apub;
-
- /**
- * Master public key of the exchange the auditor is signing
- * information for.
- */
- struct TALER_MasterPublicKeyP mpub;
-
- /**
- * Number of signatures and DKI entries in this file.
- */
- uint32_t dki_len;
-
-};
-GNUNET_NETWORK_STRUCT_END
-
-
-/**
- * Load the auditor signature and the information signed by the
- * auditor and call the callback in @a cls with the information.
- *
- * @param cls the `struct AuditorIterateContext *`
- * @param filename name of a file that should contain
- * a denomination key
- * @return #GNUNET_OK to continue to iterate
- * #GNUNET_NO to abort iteration with success
- * #GNUNET_SYSERR to abort iteration with failure
- */
-static int
-auditor_iter (void *cls,
- const char *filename)
-{
- struct AuditorIterateContext *aic = cls;
- uint64_t size;
- struct AuditorFileHeaderP *af;
- const struct TALER_AuditorSignatureP *sigs;
- const struct TALER_DenominationKeyValidityPS *dki;
- const char *auditor_url;
- unsigned int dki_len;
- size_t url_len;
- int ret;
-
- if (GNUNET_OK != GNUNET_DISK_file_size (filename,
- &size,
- GNUNET_YES,
- GNUNET_YES))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Skipping inaccessable auditor information file `%s'\n",
- filename);
- return GNUNET_SYSERR;
- }
- if (size < sizeof (struct AuditorFileHeaderP))
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- af = GNUNET_malloc (size);
- if (size !=
- GNUNET_DISK_fn_read (filename,
- af,
- size))
- {
- GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
- "read",
- filename);
- GNUNET_free (af);
- return GNUNET_SYSERR;
- }
- dki_len = ntohl (af->dki_len);
- if (0 == dki_len)
- {
- GNUNET_break_op (0);
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "No signed keys in %s\n",
- filename);
- GNUNET_free (af);
- return GNUNET_SYSERR;
- }
- if ( (size - sizeof (struct AuditorFileHeaderP)) / dki_len <
- (sizeof (struct TALER_DenominationKeyValidityPS) +
- sizeof (struct TALER_AuditorSignatureP)) )
- {
- GNUNET_break_op (0);
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Malformed key file %s\n",
- filename);
- GNUNET_free (af);
- return GNUNET_SYSERR;
- }
- url_len = size
- - sizeof (struct AuditorFileHeaderP)
- - dki_len * (sizeof (struct TALER_DenominationKeyValidityPS) +
- sizeof (struct TALER_AuditorSignatureP));
- sigs = (const struct TALER_AuditorSignatureP *) &af[1];
- dki = (const struct TALER_DenominationKeyValidityPS *) &sigs[dki_len];
- auditor_url = (const char *) &dki[dki_len];
- if ( (0 == url_len) ||
- ('\0' != auditor_url[url_len - 1]) )
- {
- GNUNET_break_op (0);
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Malformed key file %s\n",
- filename);
- GNUNET_free (af);
- return GNUNET_SYSERR;
- }
- ret = aic->it (aic->it_cls,
- &af->apub,
- auditor_url,
- &af->mpub,
- dki_len,
- sigs,
- dki);
- GNUNET_free (af);
- return ret;
-}
-
-
-/**
- * Call @a it with information for each auditor found in the @a exchange_base_dir.
- *
- * @param cfg configuration to use
- * @param it function to call with auditor information
- * @param it_cls closure for @a it
- * @return -1 on error, 0 if no files were found, otherwise
- * a positive number (however, even with a positive
- * number it is possible that @a it was never called
- * as maybe none of the files were well-formed)
- */
-int
-TALER_EXCHANGEDB_auditor_iterate (const struct GNUNET_CONFIGURATION_Handle *cfg,
- TALER_EXCHANGEDB_AuditorIterator it,
- void *it_cls)
-{
- struct AuditorIterateContext aic;
- int ret;
- char *auditor_base_dir;
-
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_filename (cfg,
- "exchangedb",
- "AUDITOR_BASE_DIR",
- &auditor_base_dir))
- return -1;
- aic.it = it;
- aic.it_cls = it_cls;
- ret = GNUNET_DISK_directory_scan (auditor_base_dir,
- &auditor_iter,
- &aic);
- GNUNET_free (auditor_base_dir);
- return ret;
-}
-
-
-/**
- * Write auditor information to the given file.
- *
- * @param filename the file where to write the auditor information to
- * @param apub the auditor's public key
- * @param auditor_url the URL of the auditor
- * @param asigs the auditor's signatures, array of length @a dki_len
- * @param mpub the exchange's public key (as expected by the auditor)
- * @param dki_len length of @a dki
- * @param dki array of denomination coin data signed by the auditor
- * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure.
- */
-int
-TALER_EXCHANGEDB_auditor_write (const char *filename,
- const struct TALER_AuditorPublicKeyP *apub,
- const char *auditor_url,
- const struct TALER_AuditorSignatureP *asigs,
- const struct TALER_MasterPublicKeyP *mpub,
- unsigned int dki_len,
- const struct TALER_DenominationKeyValidityPS *dki)
-{
- struct AuditorFileHeaderP af;
- struct GNUNET_DISK_FileHandle *fh;
- ssize_t wrote;
- size_t wsize;
- int ret;
- int eno;
-
- af.apub = *apub;
- af.mpub = *mpub;
- af.dki_len = htonl ((uint32_t) dki_len);
- ret = GNUNET_SYSERR;
- if (NULL == (fh = GNUNET_DISK_file_open
- (filename,
- GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_TRUNCATE,
- GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE)))
- goto cleanup;
- wsize = sizeof (struct AuditorFileHeaderP);
- if (GNUNET_SYSERR == (wrote = GNUNET_DISK_file_write (fh,
- &af,
- wsize)))
- goto cleanup;
- if (wrote != wsize)
- goto cleanup;
- wsize = dki_len * sizeof (struct TALER_AuditorSignatureP);
- if (wsize ==
- GNUNET_DISK_file_write (fh,
- asigs,
- wsize))
- ret = GNUNET_OK;
- wsize = dki_len * sizeof (struct TALER_DenominationKeyValidityPS);
- if (wsize ==
- GNUNET_DISK_file_write (fh,
- dki,
- wsize))
- ret = GNUNET_OK;
- wsize = strlen (auditor_url) + 1;
- if (wsize ==
- GNUNET_DISK_file_write (fh,
- auditor_url,
- wsize))
- ret = GNUNET_OK;
- cleanup:
- eno = errno;
- if (NULL != fh)
- (void) GNUNET_DISK_file_close (fh);
- errno = eno;
- return ret;
-}
-
-
-/* end of exchangedb_keyio.c */
diff --git a/src/exchangedb/exchangedb_signkeys.c b/src/exchangedb/exchangedb_signkeys.c
new file mode 100644
index 000000000..c333dec13
--- /dev/null
+++ b/src/exchangedb/exchangedb_signkeys.c
@@ -0,0 +1,175 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2014, 2015, 2016 Inria & GNUnet e.V.
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file exchangedb/exchangedb_signkeys.c
+ * @brief I/O operations for the Exchange's private online signing keys
+ * @author Florian Dold
+ * @author Benedikt Mueller
+ * @author Sree Harsha Totakura
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "taler_exchangedb_lib.h"
+
+
+/**
+ * Closure for the #signkeys_iterate_dir_iter().
+ */
+struct SignkeysIterateContext
+{
+
+ /**
+ * Function to call on each signing key.
+ */
+ TALER_EXCHANGEDB_SigningKeyIterator it;
+
+ /**
+ * Closure for @e it.
+ */
+ void *it_cls;
+};
+
+
+/**
+ * Function called on each file in the directory with our signing
+ * keys. Parses the file and calls the iterator from @a cls.
+ *
+ * @param cls the `struct SignkeysIterateContext *`
+ * @param filename name of the file to parse
+ * @return #GNUNET_OK to continue,
+ * #GNUNET_NO to stop iteration without error,
+ * #GNUNET_SYSERR to stop iteration with error
+ */
+static int
+signkeys_iterate_dir_iter (void *cls,
+ const char *filename)
+{
+ struct SignkeysIterateContext *skc = cls;
+ ssize_t nread;
+ struct TALER_EXCHANGEDB_PrivateSigningKeyInformationP issue;
+
+ nread = GNUNET_DISK_fn_read (filename,
+ &issue,
+ sizeof (struct TALER_EXCHANGEDB_PrivateSigningKeyInformationP));
+ if (nread != sizeof (struct TALER_EXCHANGEDB_PrivateSigningKeyInformationP))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Invalid signkey file `%s': wrong size (%d, expected %u)\n",
+ filename,
+ (int) nread,
+ (unsigned int) sizeof (struct TALER_EXCHANGEDB_PrivateSigningKeyInformationP));
+ return GNUNET_OK;
+ }
+ return skc->it (skc->it_cls,
+ filename,
+ &issue);
+}
+
+
+/**
+ * Call @a it for each signing key found in the @a exchange_base_dir.
+ *
+ * @param exchange_base_dir base directory for the exchange,
+ * the signing keys must be in the #TALER_EXCHANGEDB_DIR_SIGNING_KEYS
+ * subdirectory
+ * @param it function to call on each signing key
+ * @param it_cls closure for @a it
+ * @return number of files found (may not match
+ * number of keys given to @a it as malformed
+ * files are simply skipped), -1 on error
+ */
+int
+TALER_EXCHANGEDB_signing_keys_iterate (const char *exchange_base_dir,
+ TALER_EXCHANGEDB_SigningKeyIterator it,
+ void *it_cls)
+{
+ char *signkey_dir;
+ struct SignkeysIterateContext skc;
+ int ret;
+
+ GNUNET_asprintf (&signkey_dir,
+ "%s" DIR_SEPARATOR_STR TALER_EXCHANGEDB_DIR_SIGNING_KEYS,
+ exchange_base_dir);
+ skc.it = it;
+ skc.it_cls = it_cls;
+ ret = GNUNET_DISK_directory_scan (signkey_dir,
+ &signkeys_iterate_dir_iter,
+ &skc);
+ GNUNET_free (signkey_dir);
+ return ret;
+}
+
+
+/**
+ * Obtain the name of the directory we use to store signing
+ * keys created at time @a start.
+ *
+ * @param start time at which we create the signing key
+ * @return name of the directory we should use, basically "$EXCHANGEDIR/$TIME/";
+ * (valid until next call to this function)
+ */
+static char *
+get_signkey_file (const char *exchange_directory,
+ struct GNUNET_TIME_Absolute start)
+{
+ char *dir;
+
+ GNUNET_asprintf (&dir,
+ "%s" DIR_SEPARATOR_STR TALER_EXCHANGEDB_DIR_SIGNING_KEYS DIR_SEPARATOR_STR "%llu",
+ exchange_directory,
+ (unsigned long long) start.abs_value_us);
+ return dir;
+}
+
+
+/**
+ * Exports a signing key to the given file.
+ *
+ * @param exchange_base_dir base directory for the keys
+ * @param start start time of the validity for the key
+ * @param ski the signing key
+ * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure.
+ */
+int
+TALER_EXCHANGEDB_signing_key_write (const char *exchange_base_dir,
+ struct GNUNET_TIME_Absolute start,
+ const struct TALER_EXCHANGEDB_PrivateSigningKeyInformationP *ski)
+{
+ char *skf;
+ ssize_t nwrite;
+
+ skf = get_signkey_file (exchange_base_dir,
+ start);
+ if (GNUNET_OK !=
+ GNUNET_DISK_directory_create_for_file (skf))
+ return GNUNET_SYSERR;
+ nwrite = GNUNET_DISK_fn_write (skf,
+ ski,
+ sizeof (struct TALER_EXCHANGEDB_PrivateSigningKeyInformationP),
+ GNUNET_DISK_PERM_USER_WRITE | GNUNET_DISK_PERM_USER_READ);
+ if (sizeof (struct TALER_EXCHANGEDB_PrivateSigningKeyInformationP) != nwrite)
+ {
+ GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
+ "write",
+ skf);
+ GNUNET_free (skf);
+ return GNUNET_SYSERR;
+ }
+ GNUNET_free (skf);
+ return GNUNET_OK;
+}
+
+/* end of exchangedb_signkeys.c */
diff --git a/src/exchangedb/test_exchangedb_keyio.c b/src/exchangedb/test_exchangedb_denomkeys.c
index ab68f9cc2..0d6ff3a99 100644
--- a/src/exchangedb/test_exchangedb_keyio.c
+++ b/src/exchangedb/test_exchangedb_denomkeys.c
@@ -14,8 +14,8 @@
TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
*/
/**
- * @file exchangedb/test_exchangedb_keyio.c
- * @brief test cases for some functions in exchangedb/exchangedb_keyio.c
+ * @file exchangedb/test_exchangedb_denomkeys.c
+ * @brief test cases for some functions in exchangedb/exchangedb_denomkeys.c
* @author Sree Harsha Totakura <sreeharsha@totakura.in>
*/
#include "platform.h"
@@ -84,22 +84,34 @@ main (int argc,
char *enc_read;
size_t enc_read_size;
char *tmpfile;
+ char *tmpdir;
int ret;
ret = 1;
+ GNUNET_log_setup ("test-exchangedb-denomkeys",
+ "WARNING",
+ NULL);
enc = NULL;
enc_read = NULL;
tmpfile = NULL;
dki.denom_priv.rsa_private_key = NULL;
dki_read.denom_priv.rsa_private_key = NULL;
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
- &dki.issue.signature,
- sizeof (struct TALER_MasterSignatureP));
+ &dki.issue,
+ sizeof (struct TALER_EXCHANGEDB_DenominationKeyInformationP));
dki.denom_priv.rsa_private_key
= GNUNET_CRYPTO_rsa_private_key_create (RSA_KEY_SIZE);
+ dki.denom_pub.rsa_public_key
+ = GNUNET_CRYPTO_rsa_private_key_get_public (dki.denom_priv.rsa_private_key);
enc_size = GNUNET_CRYPTO_rsa_private_key_encode (dki.denom_priv.rsa_private_key,
&enc);
- EXITIF (NULL == (tmpfile = GNUNET_DISK_mktemp ("test_exchange_common")));
+ EXITIF (NULL == (tmpdir = GNUNET_DISK_mkdtemp ("test_exchangedb_dki")));
+ GNUNET_asprintf (&tmpfile,
+ "%s/%s/%s/%s",
+ tmpdir,
+ TALER_EXCHANGEDB_DIR_DENOMINATION_KEYS,
+ "cur-unit-uuid",
+ "testkey.key");
EXITIF (GNUNET_OK !=
TALER_EXCHANGEDB_denomination_key_write (tmpfile,
&dki));
@@ -107,7 +119,7 @@ main (int argc,
TALER_EXCHANGEDB_denomination_key_read (tmpfile,
&dki_read));
EXITIF (1 !=
- TALER_EXCHANGEDB_denomination_keys_iterate (tmpfile,
+ TALER_EXCHANGEDB_denomination_keys_iterate (tmpdir,
&dki_iter,
&dki));
@@ -130,6 +142,8 @@ main (int argc,
GNUNET_free_non_null (enc_read);
if (NULL != dki.denom_priv.rsa_private_key)
GNUNET_CRYPTO_rsa_private_key_free (dki.denom_priv.rsa_private_key);
+ if (NULL != dki.denom_pub.rsa_public_key)
+ GNUNET_CRYPTO_rsa_public_key_free (dki.denom_pub.rsa_public_key);
if (NULL != dki_read.denom_priv.rsa_private_key)
GNUNET_CRYPTO_rsa_private_key_free (dki_read.denom_priv.rsa_private_key);
return ret;