aboutsummaryrefslogtreecommitdiff
path: root/src/exchangedb/exchangedb_signkeys.c
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/exchangedb_signkeys.c
parent3526c44a38195aaea2ab48a220728df175ab9429 (diff)
refactoring exchangedb tests to improve coverage
Diffstat (limited to 'src/exchangedb/exchangedb_signkeys.c')
-rw-r--r--src/exchangedb/exchangedb_signkeys.c175
1 files changed, 175 insertions, 0 deletions
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 */