From 187fa67f3c8791bec65f075d285081460e5f2170 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Fri, 6 May 2016 19:22:39 +0200 Subject: refactoring exchangedb tests to improve coverage --- src/exchangedb/exchangedb_signkeys.c | 175 +++++++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 src/exchangedb/exchangedb_signkeys.c (limited to 'src/exchangedb/exchangedb_signkeys.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 +*/ +/** + * @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 */ -- cgit v1.2.3