load fees from DB instead of from config, also in wire tools

This commit is contained in:
Christian Grothoff 2020-12-16 19:23:29 +01:00
parent e0497239e9
commit 6f6c71a8d3
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
23 changed files with 647 additions and 3699 deletions

View File

@ -15,7 +15,6 @@ bin_PROGRAMS = \
taler-auditor-dbinit \
taler-auditor-exchange \
taler-auditor-httpd \
taler-auditor-sign \
taler-helper-auditor-aggregation \
taler-helper-auditor-coins \
taler-helper-auditor-deposits \
@ -156,17 +155,6 @@ taler_auditor_httpd_LDADD = \
-lz \
$(XLIB)
taler_auditor_sign_SOURCES = \
taler-auditor-sign.c
taler_auditor_sign_LDADD = \
$(LIBGCRYPT_LIBS) \
$(top_builddir)/src/util/libtalerutil.la \
$(top_builddir)/src/auditordb/libtalerauditordb.la \
$(top_builddir)/src/exchangedb/libtalerexchangedb.la \
-lgnunetutil \
$(XLIB)
taler_auditor_exchange_SOURCES = \
taler-auditor-exchange.c
taler_auditor_exchange_LDADD = \
@ -195,9 +183,7 @@ EXTRA_DIST = \
$(check_SCRIPTS) \
auditor-basedb.age \
auditor-basedb.sql \
auditor-basedb.fees \
auditor-basedb.mpub \
revoke-basedb.age \
revoke-basedb.sql \
revoke-basedb.fees \
revoke-basedb.mpub

View File

@ -1 +1 @@
1607688843
1608125224

View File

@ -1 +1 @@
7W3RY6X05KGPE78JXGGGZWQ3XKA7TW4CVBEWZQA4PRVHFZEW05WG
NKW2PKVQP9DZSBWGEX7Y7AP3BEV0MYYNZWC8WQ9EED22E74PGH50

File diff suppressed because it is too large Load Diff

View File

@ -1,437 +0,0 @@
/*
This file is part of TALER
Copyright (C) 2014, 2015, 2018 Taler Systems SA
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, see <http://www.gnu.org/licenses/>
*/
/**
* @file taler-auditor-sign.c
* @brief Tool used by the auditor to sign the exchange's master key and the
* denomination key(s).
* @author Christian Grothoff
*/
#include <platform.h>
#include "taler_exchangedb_lib.h"
#include "taler_auditordb_lib.h"
/**
* Are we running in verbose mode?
*/
static unsigned int verbose;
/**
* Filename of the auditor's private key.
*/
static char *auditor_key_file;
/**
* File with the Exchange's denomination keys to sign, itself
* signed by the Exchange's public key.
*/
static char *exchange_request_file;
/**
* Where should we write the auditor's signature?
*/
static char *output_file;
/**
* URL of the auditor (informative for the user).
*/
static char *auditor_url;
/**
* Master public key of the exchange.
*/
static struct TALER_MasterPublicKeyP master_public_key;
/**
* Our configuration.
*/
static struct GNUNET_CONFIGURATION_Handle *cfg;
/**
* Handle to access the auditor's database.
*/
static struct TALER_AUDITORDB_Plugin *adb;
/**
* Print denomination key details for diagnostics.
*
* @param dk denomination key to print
*/
static void
print_dk (const struct TALER_DenominationKeyValidityPS *dk)
{
struct TALER_Amount a;
char *s;
fprintf (stdout,
"Denomination key hash: %s\n",
GNUNET_h2s_full (&dk->denom_hash));
TALER_amount_ntoh (&a,
&dk->value);
fprintf (stdout,
"Value: %s\n",
s = TALER_amount_to_string (&a));
GNUNET_free (s);
TALER_amount_ntoh (&a,
&dk->fee_withdraw);
fprintf (stdout,
"Withdraw fee: %s\n",
s = TALER_amount_to_string (&a));
GNUNET_free (s);
TALER_amount_ntoh (&a,
&dk->fee_deposit);
fprintf (stdout,
"Deposit fee: %s\n",
s = TALER_amount_to_string (&a));
GNUNET_free (s);
TALER_amount_ntoh (&a,
&dk->fee_refresh);
fprintf (stdout,
"Refresh fee: %s\n",
s = TALER_amount_to_string (&a));
GNUNET_free (s);
TALER_amount_ntoh (&a,
&dk->fee_refund);
fprintf (stdout,
"Refund fee: %s\n",
s = TALER_amount_to_string (&a));
GNUNET_free (s);
fprintf (stdout,
"Validity start time: %s\n",
GNUNET_STRINGS_absolute_time_to_string (GNUNET_TIME_absolute_ntoh (
dk->start)));
fprintf (stdout,
"Withdraw end time: %s\n",
GNUNET_STRINGS_absolute_time_to_string (GNUNET_TIME_absolute_ntoh (
dk->expire_withdraw)));
fprintf (stdout,
"Deposit end time: %s\n",
GNUNET_STRINGS_absolute_time_to_string (GNUNET_TIME_absolute_ntoh (
dk->expire_deposit)));
fprintf (stdout,
"Legal dispute end time: %s\n",
GNUNET_STRINGS_absolute_time_to_string (GNUNET_TIME_absolute_ntoh (
dk->expire_legal)));
fprintf (stdout,
"\n");
}
/**
* The main function of the taler-auditor-sign tool. This tool is used
* to sign a exchange's master and denomination keys, affirming that the
* auditor is aware of them and will validate the exchange's database with
* respect to these keys.
*
* @param argc number of arguments from the command line
* @param argv command line arguments
* @return 0 ok, 1 on error
*/
int
main (int argc,
char *const *argv)
{
char *cfgfile = NULL;
char *loglev = NULL;
char *logfile = NULL;
const struct GNUNET_GETOPT_CommandLineOption options[] = {
GNUNET_GETOPT_option_filename ('a',
"auditor-key",
"FILENAME",
"file containing the private key of the auditor",
&auditor_key_file),
GNUNET_GETOPT_option_cfgfile (&cfgfile),
GNUNET_GETOPT_option_help ("Sign denomination keys of an exchange"),
GNUNET_GETOPT_option_loglevel (&loglev),
GNUNET_GETOPT_option_logfile (&logfile),
GNUNET_GETOPT_option_mandatory
(GNUNET_GETOPT_option_base32_auto ('m',
"exchange-key",
"KEY",
"public key of the exchange (Crockford base32 encoded)",
&master_public_key)),
GNUNET_GETOPT_option_string ('u',
"auditor-url",
"URL",
"URL of the auditor (informative link for the user)",
&auditor_url),
GNUNET_GETOPT_option_mandatory
(GNUNET_GETOPT_option_filename ('r',
"exchange-request",
"FILENAME",
"set of keys the exchange requested the auditor to sign",
&exchange_request_file)),
GNUNET_GETOPT_option_filename ('o',
"output",
"FILENAME",
"where to write our signature",
&output_file),
GNUNET_GETOPT_option_version (VERSION "-" VCS_VERSION),
GNUNET_GETOPT_option_verbose (&verbose),
GNUNET_GETOPT_OPTION_END
};
struct GNUNET_CRYPTO_EddsaPrivateKey eddsa_priv;
struct TALER_AuditorSignatureP *sigs;
struct TALER_AuditorPublicKeyP apub;
struct GNUNET_DISK_FileHandle *fh;
struct TALER_DenominationKeyValidityPS *dki;
unsigned int dki_len;
struct TALER_ExchangeKeyValidityPS kv;
off_t in_size;
if (GNUNET_GETOPT_run ("taler-auditor-sign",
options,
argc, argv) <= 0)
return 1;
GNUNET_assert (GNUNET_OK ==
GNUNET_log_setup ("taler-auditor-sign",
loglev,
logfile));
if (NULL == cfgfile)
cfgfile = GNUNET_strdup (GNUNET_OS_project_data_get ()->user_config_file);
cfg = GNUNET_CONFIGURATION_create ();
if (GNUNET_SYSERR ==
GNUNET_CONFIGURATION_load (cfg,
cfgfile))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Malformed configuration file `%s', exiting ...\n",
cfgfile);
GNUNET_free (cfgfile);
return 1;
}
GNUNET_free (cfgfile);
if ( (NULL == auditor_key_file) &&
(GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_filename (cfg,
"auditor",
"AUDITOR_PRIV_FILE",
&auditor_key_file)) )
{
fprintf (stderr,
"Auditor key file not given in neither configuration nor command-line\n");
return 1;
}
if ( (NULL == auditor_url) &&
(GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_string (cfg,
"auditor",
"AUDITOR_URL",
&auditor_url)) )
{
fprintf (stderr,
"Auditor URL not given in neither configuration nor command-line\n");
return 1;
}
if (GNUNET_SYSERR ==
GNUNET_CRYPTO_eddsa_key_from_file (auditor_key_file,
GNUNET_YES,
&eddsa_priv))
{
fprintf (stderr,
"Failed to initialize auditor private key from file `%s'\n",
auditor_key_file);
return 1;
}
GNUNET_CRYPTO_eddsa_key_get_public (&eddsa_priv,
&apub.eddsa_pub);
fh = GNUNET_DISK_file_open (exchange_request_file,
GNUNET_DISK_OPEN_READ,
GNUNET_DISK_PERM_NONE);
if (NULL == fh)
{
fprintf (stderr,
"Failed to open file `%s': %s\n",
exchange_request_file,
strerror (errno));
return 1;
}
if (GNUNET_OK !=
GNUNET_DISK_file_handle_size (fh,
&in_size))
{
fprintf (stderr,
"Failed to obtain input file size `%s': %s\n",
exchange_request_file,
strerror (errno));
GNUNET_DISK_file_close (fh);
return 1;
}
if (0 != (in_size % sizeof (struct TALER_DenominationKeyValidityPS)))
{
fprintf (stderr,
"Input file size of file `%s' is invalid\n",
exchange_request_file);
GNUNET_DISK_file_close (fh);
return 1;
}
dki_len = in_size / sizeof (struct TALER_DenominationKeyValidityPS);
if (0 == dki_len)
{
fprintf (stderr,
"Failed to produce auditor signature, denomination list is empty.\n");
GNUNET_DISK_file_close (fh);
return 2;
}
if (NULL ==
(adb = TALER_AUDITORDB_plugin_load (cfg)))
{
fprintf (stderr,
"Failed to initialize auditor database plugin.\n");
GNUNET_DISK_file_close (fh);
return 3;
}
kv.purpose.purpose = htonl (TALER_SIGNATURE_AUDITOR_EXCHANGE_KEYS);
kv.purpose.size = htonl (sizeof (struct TALER_ExchangeKeyValidityPS));
GNUNET_CRYPTO_hash (auditor_url,
strlen (auditor_url) + 1,
&kv.auditor_url_hash);
kv.master = master_public_key;
dki = GNUNET_new_array (dki_len,
struct TALER_DenominationKeyValidityPS);
if (in_size !=
GNUNET_DISK_file_read (fh,
dki,
in_size))
{
fprintf (stderr,
"Failed to read input file `%s': %s\n",
exchange_request_file,
strerror (errno));
TALER_AUDITORDB_plugin_unload (adb);
GNUNET_DISK_file_close (fh);
GNUNET_free (dki);
return 1;
}
GNUNET_DISK_file_close (fh);
sigs = GNUNET_new_array (dki_len,
struct TALER_AuditorSignatureP);
for (unsigned int i = 0; i<dki_len; i++)
{
struct TALER_DenominationKeyValidityPS *dk = &dki[i];
if (verbose)
print_dk (dk);
kv.start = dk->start;
kv.expire_withdraw = dk->expire_withdraw;
kv.expire_deposit = dk->expire_deposit;
kv.expire_legal = dk->expire_legal;
kv.value = dk->value;
kv.fee_withdraw = dk->fee_withdraw;
kv.fee_deposit = dk->fee_deposit;
kv.fee_refresh = dk->fee_refresh;
kv.fee_refund = dk->fee_refund;
kv.denom_hash = dk->denom_hash;
/* Finally sign ... */
GNUNET_CRYPTO_eddsa_sign (&eddsa_priv,
&kv,
&sigs[i].eddsa_sig);
}
if (NULL == output_file)
{
fprintf (stderr,
"Output file not given\n");
TALER_AUDITORDB_plugin_unload (adb);
GNUNET_free (dki);
GNUNET_free (sigs);
return 1;
}
/* Create required tables */
if (GNUNET_OK !=
adb->create_tables (adb->cls))
{
fprintf (stderr,
"Failed to create tables in auditor's database\n");
TALER_AUDITORDB_plugin_unload (adb);
GNUNET_free (dki);
GNUNET_free (sigs);
return 3;
}
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Taler auditor importing keys for exchange master public key %s\n",
TALER_B2S (&master_public_key));
/* Update DB */
{
enum GNUNET_DB_QueryStatus qs;
struct TALER_AUDITORDB_Session *session;
session = adb->get_session (adb->cls);
if (NULL == session)
{
fprintf (stderr,
"Failed to initialize database session\n");
TALER_AUDITORDB_plugin_unload (adb);
GNUNET_free (dki);
GNUNET_free (sigs);
return 3;
}
for (unsigned int i = 0; i<dki_len; i++)
{
const struct TALER_DenominationKeyValidityPS *dk = &dki[i];
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Adding denomination key %s to auditor database\n",
TALER_B2S (&dk->denom_hash));
qs = adb->insert_denomination_info (adb->cls,
session,
dk);
if (0 > qs)
{
fprintf (stderr,
"Failed to store key in auditor DB (did you add the exchange using taler-auditor-exchange first?)\n");
TALER_AUDITORDB_plugin_unload (adb);
GNUNET_free (dki);
GNUNET_free (sigs);
return 3;
}
}
}
TALER_AUDITORDB_plugin_unload (adb);
/* write result to disk */
if (GNUNET_OK !=
TALER_EXCHANGEDB_auditor_write (output_file,
&apub,
auditor_url,
sigs,
&master_public_key,
dki_len,
dki))
{
fprintf (stderr,
"Failed to write to file `%s': %s\n",
output_file,
strerror (errno));
GNUNET_free (sigs);
GNUNET_free (dki);
return 1;
}
GNUNET_free (sigs);
GNUNET_free (dki);
return 0;
}
/* end of taler-auditor-sign.c */

View File

@ -1798,12 +1798,6 @@ check_with_database()
# Setup database-specific globals
MASTER_PUB=`cat ${BASEDB}.mpub`
# Where to store wire fee details for aggregator
echo "Storing wire fees"
WIRE_FEE_DIR=`taler-config -c $CONF -f -s exchangedb -o WIREFEE_BASE_DIR`
mkdir -p $WIRE_FEE_DIR
cp ${BASEDB}.fees $WIRE_FEE_DIR/x-taler-bank.fee
# Determine database age
echo "Calculating database age based on ${BASEDB}.age"
AGE=`cat ${BASEDB}.age`

View File

@ -472,12 +472,6 @@ check_with_database()
# Setup database-specific globals
MASTER_PUB=`cat ${BASEDB}.mpub`
# Where to store wire fee details for aggregator
echo "Storing wire fees"
WIRE_FEE_DIR=`taler-config -c $CONF -f -s exchangedb -o WIREFEE_BASE_DIR`
mkdir -p $WIRE_FEE_DIR
cp ${BASEDB}.fees $WIRE_FEE_DIR/x-taler-bank.fee
# Determine database age
echo "Calculating database age based on ${BASEDB}.age"
AGE=`cat ${BASEDB}.age`

View File

@ -455,21 +455,29 @@ deposit_cb (void *cls,
au->execution_time = GNUNET_TIME_absolute_get ();
(void) GNUNET_TIME_round_abs (&au->execution_time);
{
struct TALER_EXCHANGEDB_AggregateFees *af;
struct TALER_Amount closing_fee;
struct GNUNET_TIME_Absolute start_date;
struct GNUNET_TIME_Absolute end_date;
struct TALER_MasterSignatureP master_sig;
enum GNUNET_DB_QueryStatus qs;
af = TALER_EXCHANGEDB_update_fees (cfg,
db_plugin,
au->wa,
qs = db_plugin->get_wire_fee (db_plugin->cls,
au->session,
au->wa->method,
au->execution_time,
au->session);
if (NULL == af)
&start_date,
&end_date,
&au->wire_fee,
&closing_fee,
&master_sig);
if (0 >= qs)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Could not get or persist wire fees for %s. Aborting run.\n",
"Could not get wire fees for %s at %s. Aborting run.\n",
au->wa->method,
GNUNET_STRINGS_absolute_time_to_string (au->execution_time));
return GNUNET_DB_STATUS_HARD_ERROR;
}
au->wire_fee = af->wire_fee;
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,

View File

@ -248,7 +248,7 @@ expired_reserve_cb (void *cls,
struct GNUNET_TIME_Absolute now;
struct TALER_WireTransferIdentifierRawP wtid;
struct TALER_Amount amount_without_fee;
const struct TALER_Amount *closing_fee;
struct TALER_Amount closing_fee;
int ret;
enum GNUNET_DB_QueryStatus qs;
struct TALER_EXCHANGEDB_WireAccount *wa;
@ -276,32 +276,41 @@ expired_reserve_cb (void *cls,
/* lookup `closing_fee` from time of actual reserve expiration
(we may be lagging behind!) */
{
struct TALER_EXCHANGEDB_AggregateFees *af;
struct TALER_Amount wire_fee;
struct GNUNET_TIME_Absolute start_date;
struct GNUNET_TIME_Absolute end_date;
struct TALER_MasterSignatureP master_sig;
enum GNUNET_DB_QueryStatus qs;
af = TALER_EXCHANGEDB_update_fees (cfg,
db_plugin,
wa,
qs = db_plugin->get_wire_fee (db_plugin->cls,
session,
wa->method,
expiration_date,
session);
if (NULL == af)
&start_date,
&end_date,
&wire_fee,
&closing_fee,
&master_sig);
if (0 >= qs)
{
global_ret = GR_WIRE_TRANSFER_FEES_NOT_CONFIGURED;
GNUNET_SCHEDULER_shutdown ();
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Could not get wire fees for %s at %s. Aborting run.\n",
wa->method,
GNUNET_STRINGS_absolute_time_to_string (expiration_date));
return GNUNET_DB_STATUS_HARD_ERROR;
}
closing_fee = &af->closing_fee;
}
/* calculate transfer amount */
ret = TALER_amount_subtract (&amount_without_fee,
left,
closing_fee);
&closing_fee);
if ( (GNUNET_SYSERR == ret) ||
(GNUNET_NO == ret) )
{
/* Closing fee higher than or equal to remaining balance, close
without wire transfer. */
closing_fee = left;
closing_fee = *left;
GNUNET_assert (GNUNET_OK ==
TALER_amount_get_zero (left->currency,
&amount_without_fee));
@ -337,7 +346,7 @@ expired_reserve_cb (void *cls,
account_payto_uri,
&wtid,
left,
closing_fee);
&closing_fee);
else
qs = GNUNET_DB_STATUS_HARD_ERROR;
GNUNET_log (GNUNET_ERROR_TYPE_INFO,

View File

@ -53,11 +53,7 @@ lib_LTLIBRARIES = \
libtalerexchangedb_la_SOURCES = \
exchangedb_accounts.c \
exchangedb_auditorkeys.c \
exchangedb_denomkeys.c \
exchangedb_fees.c \
exchangedb_plugin.c \
exchangedb_signkeys.c \
exchangedb_transactions.c
libtalerexchangedb_la_LIBADD = \
$(top_builddir)/src/bank-lib/libtalerbank.la \
@ -71,51 +67,11 @@ libtalerexchangedb_la_LDFLAGS = \
check_PROGRAMS = \
test-exchangedb-auditors \
test-exchangedb-denomkeys \
test-exchangedb-fees \
test-exchangedb-signkeys \
test-exchangedb-postgres
AM_TESTS_ENVIRONMENT=export TALER_PREFIX=$${TALER_PREFIX:-@libdir@};export PATH=$${TALER_PREFIX:-@prefix@}/bin:$$PATH;
TESTS = \
test-exchangedb-auditors \
test-exchangedb-denomkeys \
test-exchangedb-fees \
test-exchangedb-postgres \
test-exchangedb-signkeys
test_exchangedb_auditors_SOURCES = \
test_exchangedb_auditors.c
test_exchangedb_auditors_LDADD = \
libtalerexchangedb.la \
$(top_srcdir)/src/util/libtalerutil.la \
-lgnunetutil \
$(XLIB)
test_exchangedb_denomkeys_SOURCES = \
test_exchangedb_denomkeys.c
test_exchangedb_denomkeys_LDADD = \
libtalerexchangedb.la \
$(top_srcdir)/src/util/libtalerutil.la \
-lgnunetutil \
$(XLIB)
test_exchangedb_fees_SOURCES = \
test_exchangedb_fees.c
test_exchangedb_fees_LDADD = \
libtalerexchangedb.la \
$(top_srcdir)/src/util/libtalerutil.la \
-lgnunetutil \
$(XLIB)
test_exchangedb_signkeys_SOURCES = \
test_exchangedb_signkeys.c
test_exchangedb_signkeys_LDADD = \
libtalerexchangedb.la \
$(top_srcdir)/src/util/libtalerutil.la \
-lgnunetutil \
$(XLIB)
test-exchangedb-postgres
test_exchangedb_postgres_SOURCES = \
test_exchangedb.c

View File

@ -305,7 +305,6 @@ TALER_EXCHANGEDB_unload_accounts (void)
wa_tail,
wa);
TALER_BANK_auth_free (&wa->auth);
TALER_EXCHANGEDB_fees_free (wa->af);
GNUNET_free (wa->section_name);
GNUNET_free (wa->method);
GNUNET_free (wa);

View File

@ -1,344 +0,0 @@
/*
This file is part of TALER
Copyright (C) 2014--2019 Taler Systems SA
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, 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;
/**
* Status of the iteration.
*/
int status;
};
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;
uint32_t dki_len;
size_t url_len;
int iret;
if (GNUNET_OK !=
GNUNET_DISK_file_size (filename,
&size,
GNUNET_YES,
GNUNET_YES))
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Skipping inaccessible auditor information file `%s'\n",
filename);
return GNUNET_OK;
}
if (size < sizeof (struct AuditorFileHeaderP))
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"File size (%llu bytes) too small for file `%s' to contain auditor data. Skipping it.\n",
(unsigned long long) size,
filename);
return GNUNET_OK;
}
if (size >= GNUNET_MAX_MALLOC_CHECKED)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"File size (%llu bytes) too large for file `%s' to contain auditor data. Skipping it.\n",
(unsigned long long) size,
filename);
return GNUNET_OK;
}
af = GNUNET_malloc (size);
if (((ssize_t) size) !=
GNUNET_DISK_fn_read (filename,
af,
size))
{
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
"read",
filename);
GNUNET_free (af);
return GNUNET_OK;
}
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_OK;
}
size -= sizeof (struct AuditorFileHeaderP);
if ( (size / dki_len) <
(sizeof (struct TALER_DenominationKeyValidityPS)
+ sizeof (struct TALER_AuditorSignatureP)) )
{
GNUNET_break_op (0);
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Malformed auditor data file %s (file too short for %u keys)\n",
filename,
(unsigned int) dki_len);
GNUNET_free (af);
return GNUNET_OK;
}
url_len = size - 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 auditor data file %s (no 0-terminator)\n",
filename);
GNUNET_free (af);
return GNUNET_OK;
}
if (GNUNET_OK !=
(iret = aic->it (aic->it_cls,
&af->apub,
auditor_url,
&af->mpub,
dki_len,
sigs,
dki)))
{
GNUNET_free (af);
if (GNUNET_SYSERR == iret)
aic->status = GNUNET_SYSERR;
return GNUNET_SYSERR;
}
aic->status++;
GNUNET_free (af);
return GNUNET_OK;
}
/**
* 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;
aic.status = 0;
ret = GNUNET_DISK_directory_scan (auditor_base_dir,
&auditor_iter,
&aic);
GNUNET_free (auditor_base_dir);
if ( (0 != aic.status) ||
(GNUNET_OK == ret) )
return aic.status;
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,
uint32_t dki_len,
const struct TALER_DenominationKeyValidityPS *dki)
{
struct GNUNET_DISK_FileHandle *fh;
ssize_t wrote;
size_t wsize;
int eno;
if (GNUNET_OK !=
GNUNET_DISK_directory_create_for_file (filename))
{
eno = errno;
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
"mkdir (for file)",
filename);
errno = eno;
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)))
{
eno = errno;
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
"open",
filename);
errno = eno;
return GNUNET_SYSERR;
}
{
struct AuditorFileHeaderP af = {
.apub = *apub,
.mpub = *mpub,
.dki_len = htonl (dki_len)
};
wsize = sizeof (struct AuditorFileHeaderP);
if ( (GNUNET_SYSERR == (wrote = GNUNET_DISK_file_write (fh,
&af,
wsize))) ||
(wrote != (ssize_t) wsize) )
goto cleanup;
}
wsize = dki_len * sizeof (struct TALER_AuditorSignatureP);
if (((ssize_t) wsize) !=
GNUNET_DISK_file_write (fh,
asigs,
wsize))
goto cleanup;
wsize = dki_len * sizeof (struct TALER_DenominationKeyValidityPS);
if (((ssize_t) wsize) !=
GNUNET_DISK_file_write (fh,
dki,
wsize))
goto cleanup;
wsize = strlen (auditor_url) + 1;
if (((ssize_t) wsize) !=
GNUNET_DISK_file_write (fh,
auditor_url,
wsize))
goto cleanup;
GNUNET_assert (GNUNET_OK ==
GNUNET_DISK_file_close (fh));
return GNUNET_OK;
cleanup:
eno = errno;
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
"write",
filename);
GNUNET_break (GNUNET_OK ==
GNUNET_DISK_file_close (fh));
/* try to remove the file, as it must be malformed */
if (0 != unlink (filename))
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
"unlink",
filename);
errno = eno;
return GNUNET_SYSERR;
}
/* end of exchangedb_auditorkeys.c */

View File

@ -1,518 +0,0 @@
/*
This file is part of TALER
Copyright (C) 2014-2019 Taler Systems SA
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, 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_crypto_lib.h"
#include "taler_exchangedb_lib.h"
GNUNET_NETWORK_STRUCT_BEGIN
/**
* Contents of a file with a revocation certificate.
*/
struct RevocationFileP
{
/**
* Hash of the denomination public key being revoked.
*/
struct GNUNET_HashCode denom_hash;
/**
* Master signature over the revocation, must match purpose
* #TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED.
*/
struct TALER_MasterSignatureP msig;
};
GNUNET_NETWORK_STRUCT_END
/**
* Mark the given denomination key as revoked and request the wallets
* to initiate /recoup.
*
* @param revocation_dir where to write the revocation certificate
* @param denom_hash hash of the denomination key to revoke
* @param mpriv master private key to sign with
* @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure.
*/
int
TALER_EXCHANGEDB_denomination_key_revoke (
const char *revocation_dir,
const struct GNUNET_HashCode *denom_hash,
const struct TALER_MasterPrivateKeyP *mpriv)
{
char *fn;
int ret;
struct RevocationFileP rd;
TALER_exchange_offline_denomination_revoke_sign (denom_hash,
mpriv,
&rd.msig);
GNUNET_asprintf (&fn,
"%s" DIR_SEPARATOR_STR
"%s.rev",
revocation_dir,
GNUNET_h2s_full (denom_hash));
rd.denom_hash = *denom_hash;
ret = (sizeof (rd) !=
GNUNET_DISK_fn_write (fn,
&rd,
sizeof (rd),
GNUNET_DISK_PERM_USER_READ
| GNUNET_DISK_PERM_USER_WRITE))
? GNUNET_SYSERR
: GNUNET_OK;
GNUNET_free (fn);
return ret;
}
/**
* 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_DenominationKey *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 inaccessible denomination key file `%s'\n",
filename);
return GNUNET_SYSERR;
}
offset = sizeof (struct TALER_EXCHANGEDB_DenominationKeyInformationP);
if (size <= offset)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"File size (%llu bytes) too small for file `%s' to contain denomination key data. Skipping it.\n",
(unsigned long long) size,
filename);
return GNUNET_SYSERR;
}
if (size >= GNUNET_MAX_MALLOC_CHECKED)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"File size (%llu bytes) too large for file `%s' to contain denomination key data. Skipping it.\n",
(unsigned long long) size,
filename);
return GNUNET_OK;
}
data = GNUNET_malloc (size);
if (((ssize_t) 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);
if (0 == GNUNET_TIME_absolute_get_remaining
(GNUNET_TIME_absolute_ntoh
(dki->issue.properties.expire_withdraw)).rel_value_us)
{
/* key expired for withdrawal, remove private key to
minimize chance of compromise */
if (0 != unlink (filename))
{
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
"unlink",
filename);
/* yes, we had an error, but the file content
was fine and is being returned */
return GNUNET_OK;
}
}
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_DenominationKey *dki)
{
struct GNUNET_DISK_FileHandle *fh;
ssize_t wrote;
size_t wsize;
int eno;
if (GNUNET_OK !=
GNUNET_DISK_directory_create_for_file (filename))
{
eno = errno;
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
"mkdir (for file)",
filename);
errno = eno;
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_OPEN_FAILIFEXISTS,
GNUNET_DISK_PERM_USER_READ
| GNUNET_DISK_PERM_USER_WRITE)))
{
eno = errno;
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
"open",
filename);
errno = eno;
return GNUNET_SYSERR;
}
wsize = sizeof (struct TALER_EXCHANGEDB_DenominationKeyInformationP);
if ( (GNUNET_SYSERR == (wrote = GNUNET_DISK_file_write (fh,
&dki->issue,
wsize))) ||
(wrote != (ssize_t) wsize) )
goto cleanup;
{
void *priv_enc;
size_t priv_enc_size;
priv_enc_size
= GNUNET_CRYPTO_rsa_private_key_encode (dki->denom_priv.rsa_private_key,
&priv_enc);
wrote = GNUNET_DISK_file_write (fh,
priv_enc,
priv_enc_size);
GNUNET_free (priv_enc);
if ( (GNUNET_SYSERR == wrote) ||
(wrote != (ssize_t) priv_enc_size) )
goto cleanup;
}
GNUNET_assert (GNUNET_OK ==
GNUNET_DISK_file_close (fh));
return GNUNET_OK;
cleanup:
eno = errno;
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
"write",
filename);
GNUNET_break (GNUNET_OK ==
GNUNET_DISK_file_close (fh));
/* try to remove the file, as it must be malformed */
if (0 != unlink (filename))
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
"unlink",
filename);
errno = eno;
return GNUNET_SYSERR;
}
/**
* 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_DenominationKey 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)
{
struct DenomkeysIterateContext dic = {
.it = it,
.it_cls = it_cls
};
char *dir;
int ret;
GNUNET_asprintf (&dir,
"%s" DIR_SEPARATOR_STR
TALER_EXCHANGEDB_DIR_DENOMINATION_KEYS,
exchange_base_dir);
ret = GNUNET_DISK_directory_scan (dir,
&denomkeys_iterate_topdir_iter,
&dic);
GNUNET_free (dir);
return ret;
}
/**
* Closure for #revocations_iterate_cb().
*/
struct RevocationsIterateContext
{
/**
* Function to call on each revoked denomination key.
*/
TALER_EXCHANGEDB_RevocationIterator it;
/**
* Closure for @e it.
*/
void *it_cls;
/**
* Master public key to use to validate revocations.
*/
const struct TALER_MasterPublicKeyP *master_pub;
};
/**
* Decode the revocation certificate in the given file @a filename and call
* the callback in @a cls with the information.
*
* @param cls the `struct RevocationsIterateContext *`
* @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
revocations_iterate_cb (void *cls,
const char *filename)
{
struct RevocationsIterateContext *ric = cls;
struct RevocationFileP rf;
ssize_t rd;
/* Check if revocation is valid... */
rd = GNUNET_DISK_fn_read (filename,
&rf,
sizeof (rf));
if (GNUNET_SYSERR == rd)
{
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
"read",
filename);
return GNUNET_OK;
}
if (sizeof (rf) != (size_t) rd)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Invalid revocation file `%s' found and ignored (bad size: %llu)\n",
filename,
(unsigned long long) rd);
return GNUNET_OK;
}
if (GNUNET_OK !=
TALER_exchange_offline_denomination_revoke_verify (
&rf.denom_hash,
ric->master_pub,
&rf.msig))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Invalid revocation file `%s' found and ignored (bad signature)\n",
filename);
return GNUNET_OK;
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Denomination key `%s' was revoked!\n",
GNUNET_h2s (&rf.denom_hash));
return ric->it (ric->it_cls,
&rf.denom_hash,
&rf.msig);
}
/**
* Call @a it for each revoked denomination key found in the @a revocation_dir.
*
* @param revocation_dir base directory where revocations are stored
* @param master_pub master public key (used to check revocations)
* @param it function to call on each revoked 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_revocations_iterate (const char *revocation_dir,
const struct
TALER_MasterPublicKeyP *master_pub,
TALER_EXCHANGEDB_RevocationIterator it,
void *it_cls)
{
struct RevocationsIterateContext ric = {
.it = it,
.it_cls = it_cls,
.master_pub = master_pub
};
if (GNUNET_OK !=
GNUNET_DISK_directory_create (revocation_dir))
{
/* directory doesn't exist and we couldn't even create it,
clearly means there are no revocations there */
return 0;
}
return GNUNET_DISK_directory_scan (revocation_dir,
&revocations_iterate_cb,
&ric);
}
/* end of exchangedb_denomkeys.c */

View File

@ -1,412 +0,0 @@
/*
This file is part of TALER
Copyright (C) 2017 Taler Systems SA
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, see <http://www.gnu.org/licenses/>
*/
/**
* @file exchangedb/exchangedb_fees.c
* @brief Logic to read/write/convert aggregation wire fees (not other fees!)
* @author Christian Grothoff
*/
#include "platform.h"
#include "taler_exchangedb_lib.h"
GNUNET_NETWORK_STRUCT_BEGIN
/**
* Structure for wire fees on disk.
*/
struct TALER_WireFeeDiskP
{
/**
* Wire fee details.
*/
struct TALER_MasterWireFeePS wf;
/**
* Signature affirming the above fee structure.
*/
struct TALER_MasterSignatureP master_sig;
};
GNUNET_NETWORK_STRUCT_END
/**
* Convert @a wd disk format to host format.
*
* @param wd aggregate fees, disk format
* @return fees in host format
*/
static struct TALER_EXCHANGEDB_AggregateFees *
wd2af (const struct TALER_WireFeeDiskP *wd)
{
struct TALER_EXCHANGEDB_AggregateFees *af;
af = GNUNET_new (struct TALER_EXCHANGEDB_AggregateFees);
af->start_date = GNUNET_TIME_absolute_ntoh (wd->wf.start_date);
af->end_date = GNUNET_TIME_absolute_ntoh (wd->wf.end_date);
TALER_amount_ntoh (&af->wire_fee,
&wd->wf.wire_fee);
TALER_amount_ntoh (&af->closing_fee,
&wd->wf.closing_fee);
af->master_sig = wd->master_sig;
return af;
}
/**
* Read the current fee structure from disk.
*
* @param cfg configuration to use
* @param wireplugin name of the wire plugin to read fees for
* @return sorted list of aggregation fees, NULL on error
*/
struct TALER_EXCHANGEDB_AggregateFees *
TALER_EXCHANGEDB_fees_read (const struct GNUNET_CONFIGURATION_Handle *cfg,
const char *wireplugin)
{
char *wirefee_base_dir;
char *fn;
struct GNUNET_DISK_FileHandle *fh;
struct TALER_WireFeeDiskP wd;
struct TALER_EXCHANGEDB_AggregateFees *af;
struct TALER_EXCHANGEDB_AggregateFees *endp;
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_filename (cfg,
"exchangedb",
"WIREFEE_BASE_DIR",
&wirefee_base_dir))
{
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING,
"exchangedb",
"WIREFEE_BASE_DIR");
return NULL;
}
GNUNET_asprintf (&fn,
"%s/%s.fee",
wirefee_base_dir,
wireplugin);
GNUNET_free (wirefee_base_dir);
fh = GNUNET_DISK_file_open (fn,
GNUNET_DISK_OPEN_READ,
GNUNET_DISK_PERM_NONE);
if (NULL == fh)
{
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
"open",
fn);
GNUNET_free (fn);
return NULL;
}
af = NULL;
endp = NULL;
while (1)
{
struct TALER_EXCHANGEDB_AggregateFees *n;
ssize_t in = GNUNET_DISK_file_read (fh,
&wd,
sizeof (wd));
if (-1 == in)
{
/* Unexpected I/O error */
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
"read",
fn);
GNUNET_break (GNUNET_OK ==
GNUNET_DISK_file_close (fh));
GNUNET_free (fn);
TALER_EXCHANGEDB_fees_free (af);
return NULL;
}
if (0 == in)
break; /* EOF, terminate normally */
if (sizeof (wd) != in)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"File `%s' has wrong size for fee structure\n",
fn);
GNUNET_break (GNUNET_OK ==
GNUNET_DISK_file_close (fh));
GNUNET_free (fn);
TALER_EXCHANGEDB_fees_free (af);
return NULL;
}
n = wd2af (&wd);
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Loaded wire fees starting at %s from file\n",
GNUNET_STRINGS_absolute_time_to_string (n->start_date));
if ( ( (NULL == af) ||
(endp->end_date.abs_value_us == n->start_date.abs_value_us) ) &&
(n->start_date.abs_value_us < n->end_date.abs_value_us) )
{
/* append to list */
if (NULL != endp)
endp->next = n;
else
af = n;
endp = n;
}
else
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"File `%s' does not have wire fees in chronological order\n",
fn);
GNUNET_DISK_file_close (fh);
GNUNET_free (n);
GNUNET_free (fn);
TALER_EXCHANGEDB_fees_free (af);
return NULL;
}
}
GNUNET_assert (GNUNET_OK ==
GNUNET_DISK_file_close (fh));
GNUNET_free (fn);
return af;
}
/**
* Convert @a af to @a wf.
*
* @param wiremethod name of the wire method the fees are for
* @param[in,out] af aggregate fees, host format (updated to round time)
* @param[out] wf aggregate fees, disk / signature format
*/
void
TALER_EXCHANGEDB_fees_2_wf (const char *wiremethod,
struct TALER_EXCHANGEDB_AggregateFees *af,
struct TALER_MasterWireFeePS *wf)
{
(void) GNUNET_TIME_round_abs (&af->start_date);
(void) GNUNET_TIME_round_abs (&af->end_date);
wf->purpose.size = htonl (sizeof (*wf));
wf->purpose.purpose = htonl (TALER_SIGNATURE_MASTER_WIRE_FEES);
GNUNET_CRYPTO_hash (wiremethod,
strlen (wiremethod) + 1,
&wf->h_wire_method);
wf->start_date = GNUNET_TIME_absolute_hton (af->start_date);
wf->end_date = GNUNET_TIME_absolute_hton (af->end_date);
TALER_amount_hton (&wf->wire_fee,
&af->wire_fee);
TALER_amount_hton (&wf->closing_fee,
&af->closing_fee);
}
/**
* Write given fee structure to disk.
*
* @param filename where to write the fees
* @param wireplugin which plugin the fees are about
* @param af fee structure to write
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
*/
int
TALER_EXCHANGEDB_fees_write (const char *filename,
const char *wireplugin,
struct TALER_EXCHANGEDB_AggregateFees *af)
{
struct GNUNET_DISK_FileHandle *fh;
struct TALER_WireFeeDiskP wd;
struct TALER_EXCHANGEDB_AggregateFees *last;
if (GNUNET_OK !=
GNUNET_DISK_directory_create_for_file (filename))
{
int eno;
eno = errno;
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
"mkdir (for file)",
filename);
errno = eno;
return GNUNET_SYSERR;
}
fh = GNUNET_DISK_file_open (filename,
GNUNET_DISK_OPEN_WRITE
| GNUNET_DISK_OPEN_TRUNCATE
| GNUNET_DISK_OPEN_CREATE,
GNUNET_DISK_PERM_USER_READ
| GNUNET_DISK_PERM_USER_WRITE);
if (NULL == fh)
{
int eno;
eno = errno;
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
"open",
filename);
errno = eno;
return GNUNET_SYSERR;
}
last = NULL;
while (NULL != af)
{
if ( ( (NULL != last) &&
(last->end_date.abs_value_us != af->start_date.abs_value_us) ) ||
(af->start_date.abs_value_us >= af->end_date.abs_value_us) )
{
/* @a af malformed, refusing to write file that will be rejected */
GNUNET_break (0);
GNUNET_assert (GNUNET_OK ==
GNUNET_DISK_file_close (fh));
/* try to remove the file, as it would be malformed */
if (0 != unlink (filename))
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
"unlink",
filename);
errno = EINVAL; /* invalid inputs */
return GNUNET_SYSERR;
}
TALER_EXCHANGEDB_fees_2_wf (wireplugin,
af,
&wd.wf);
wd.master_sig = af->master_sig;
last = af;
af = af->next;
if (sizeof (wd) !=
GNUNET_DISK_file_write (fh,
&wd,
sizeof (wd)))
{
int eno = errno;
GNUNET_break (GNUNET_OK ==
GNUNET_DISK_file_close (fh));
/* try to remove the file, as it must be malformed */
if (0 != unlink (filename))
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
"unlink",
filename);
errno = eno;
return GNUNET_SYSERR;
}
}
GNUNET_assert (GNUNET_OK ==
GNUNET_DISK_file_close (fh));
return GNUNET_OK;
}
/**
* Free @a af data structure
*
* @param af list to free
*/
void
TALER_EXCHANGEDB_fees_free (struct TALER_EXCHANGEDB_AggregateFees *af)
{
while (NULL != af)
{
struct TALER_EXCHANGEDB_AggregateFees *next;
next = af->next;
GNUNET_free (af);
af = next;
}
}
/**
* Find the record valid at time @a now in the fee structure.
*
* @param wa wire transfer fee data structure to update
* @param now timestamp to update fees to
* @return fee valid at @a now, or NULL if unknown
*/
static struct TALER_EXCHANGEDB_AggregateFees *
advance_fees (struct TALER_EXCHANGEDB_WireAccount *wa,
struct GNUNET_TIME_Absolute now)
{
struct TALER_EXCHANGEDB_AggregateFees *af;
af = wa->af;
while ( (NULL != af) &&
(af->end_date.abs_value_us < now.abs_value_us) )
af = af->next;
return af;
}
/**
* Update wire transfer fee data structure in @a wa.
*
* @param cfg configuration to use
* @param db_plugin database plugin to use
* @param wa wire account data structure to update
* @param now timestamp to update fees to
* @param session DB session to use
* @return fee valid at @a now, or NULL if unknown
*/
struct TALER_EXCHANGEDB_AggregateFees *
TALER_EXCHANGEDB_update_fees (const struct GNUNET_CONFIGURATION_Handle *cfg,
struct TALER_EXCHANGEDB_Plugin *db_plugin,
struct TALER_EXCHANGEDB_WireAccount *wa,
struct GNUNET_TIME_Absolute now,
struct TALER_EXCHANGEDB_Session *session)
{
enum GNUNET_DB_QueryStatus qs;
struct TALER_EXCHANGEDB_AggregateFees *af;
af = advance_fees (wa,
now);
if (NULL != af)
return af;
/* Let's try to load it from disk... */
wa->af = TALER_EXCHANGEDB_fees_read (cfg,
wa->method);
for (struct TALER_EXCHANGEDB_AggregateFees *p = wa->af;
NULL != p;
p = p->next)
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Persisting fees starting at %s in database\n",
GNUNET_STRINGS_absolute_time_to_string (p->start_date));
qs = db_plugin->insert_wire_fee (db_plugin->cls,
session,
wa->method,
p->start_date,
p->end_date,
&p->wire_fee,
&p->closing_fee,
&p->master_sig);
if (qs < 0)
{
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
TALER_EXCHANGEDB_fees_free (wa->af);
wa->af = NULL;
return NULL;
}
}
af = advance_fees (wa,
now);
if (NULL != af)
return af;
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failed to find current wire transfer fees for `%s' at %s\n",
wa->method,
GNUNET_STRINGS_absolute_time_to_string (now));
return NULL;
}
/* end of exchangedb_fees.c */

View File

@ -1,187 +0,0 @@
/*
This file is part of TALER
Copyright (C) 2014, 2015, 2016, 2020 Taler Systems SA
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, 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;
}
if (0 == GNUNET_TIME_absolute_get_remaining
(GNUNET_TIME_absolute_ntoh (issue.issue.expire)).rel_value_us)
{
if (0 != unlink (filename))
{
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
"unlink",
filename);
return GNUNET_OK; /* yes, we had an error, but continue to iterate anyway */
}
/* Expired file deleted, continue to iterate -without- calling iterator
as this key is expired */
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)
{
struct SignkeysIterateContext skc = {
.it = it,
.it_cls = it_cls
};
char *signkey_dir;
int ret;
GNUNET_asprintf (&signkey_dir,
"%s" DIR_SEPARATOR_STR TALER_EXCHANGEDB_DIR_SIGNING_KEYS,
exchange_base_dir);
ret = GNUNET_DISK_directory_scan (signkey_dir,
&signkeys_iterate_dir_iter,
&skc);
GNUNET_free (signkey_dir);
return ret;
}
/**
* 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;
GNUNET_asprintf (&skf,
"%s" DIR_SEPARATOR_STR TALER_EXCHANGEDB_DIR_SIGNING_KEYS
DIR_SEPARATOR_STR "%llu",
exchange_base_dir,
(unsigned long long) start.abs_value_us);
if (GNUNET_OK !=
GNUNET_DISK_directory_create_for_file (skf))
{
int eno;
eno = errno;
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
"mkdir (for file)",
skf);
errno = eno;
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) !=
(size_t) 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 */

View File

@ -1,169 +0,0 @@
/*
This file is part of TALER
Copyright (C) 2016 Taler Systems SA
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, see <http://www.gnu.org/licenses/>
*/
/**
* @file exchangedb/test_exchangedb_auditors.c
* @brief test cases for some functions in exchangedb/exchangedb_auditorkeys.c
* @author Christian Grothoff
*/
#include "platform.h"
#include "gnunet/gnunet_util_lib.h"
#include "taler_signatures.h"
#include "taler_exchangedb_lib.h"
#define RSA_KEY_SIZE 1024
#define EXITIF(cond) \
do { \
if (cond) { GNUNET_break (0); goto EXITIF_exit; } \
} while (0)
static struct TALER_AuditorPublicKeyP want_apub;
static struct TALER_AuditorSignatureP want_asigs;
static struct TALER_MasterPublicKeyP want_mpub;
static struct TALER_DenominationKeyValidityPS want_dki;
/**
* @brief Function called with auditor information.
*
* @param cls NULL
* @param apub the auditor's public key
* @param auditor_url URL of the auditor
* @param mpub the exchange's public key (as expected by the auditor)
* @param dki_len length of @a asig and @a dki arrays
* @param asigs array of the auditor's signatures over the @a dks, of length @a dki_len
* @param dki array of denomination coin data signed by the auditor, of length @a dki_len
* @return #GNUNET_OK to continue to iterate,
* #GNUNET_NO to stop iteration with no error,
* #GNUNET_SYSERR to abort iteration with error!
*/
static int
auditor_cb (void *cls,
const struct TALER_AuditorPublicKeyP *apub,
const char *auditor_url,
const struct TALER_MasterPublicKeyP *mpub,
unsigned int dki_len,
const struct TALER_AuditorSignatureP *asigs,
const struct TALER_DenominationKeyValidityPS *dki)
{
GNUNET_assert (NULL == cls);
if (0 != strcmp (auditor_url,
"http://auditor/"))
{
GNUNET_break (0);
return GNUNET_SYSERR;
}
if (1 != dki_len)
{
GNUNET_break (0);
return GNUNET_SYSERR;
}
if (0 != GNUNET_memcmp (&want_apub,
apub))
{
GNUNET_break (0);
return GNUNET_SYSERR;
}
if (0 != GNUNET_memcmp (&want_mpub,
mpub))
{
GNUNET_break (0);
return GNUNET_SYSERR;
}
if (0 != GNUNET_memcmp (&want_asigs,
asigs))
{
GNUNET_break (0);
return GNUNET_SYSERR;
}
if (0 != GNUNET_memcmp (&want_dki,
dki))
{
GNUNET_break (0);
return GNUNET_SYSERR;
}
return GNUNET_OK;
}
int
main (int argc,
const char *const argv[])
{
char *tmpfile = NULL;
char *tmpdir;
struct GNUNET_CONFIGURATION_Handle *cfg = NULL;
int ret;
(void) argc;
(void) argv;
ret = 1;
GNUNET_log_setup ("test-exchangedb-auditors",
"WARNING",
NULL);
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
&want_apub,
sizeof (want_apub));
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
&want_asigs,
sizeof (want_asigs));
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
&want_mpub,
sizeof (want_mpub));
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
&want_dki,
sizeof (struct TALER_DenominationKeyValidityPS));
EXITIF (NULL == (tmpdir = GNUNET_DISK_mkdtemp ("test_exchangedb_auditors")));
GNUNET_asprintf (&tmpfile,
"%s/%s",
tmpdir,
"testauditor");
EXITIF (GNUNET_OK !=
TALER_EXCHANGEDB_auditor_write (tmpfile,
&want_apub,
"http://auditor/",
&want_asigs,
&want_mpub,
1,
&want_dki));
cfg = GNUNET_CONFIGURATION_create ();
GNUNET_CONFIGURATION_set_value_string (cfg,
"exchangedb",
"AUDITOR_BASE_DIR",
tmpdir);
EXITIF (1 !=
TALER_EXCHANGEDB_auditor_iterate (cfg,
&auditor_cb,
NULL));
ret = 0;
EXITIF_exit:
if (NULL != tmpdir)
{
(void) GNUNET_DISK_directory_remove (tmpdir);
GNUNET_free (tmpdir);
}
if (NULL != cfg)
GNUNET_CONFIGURATION_destroy (cfg);
GNUNET_free (tmpfile);
return ret;
}

View File

@ -1,213 +0,0 @@
/*
This file is part of TALER
Copyright (C) 2014-2017 Taler Systems SA (and other contributing authors)
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, see <http://www.gnu.org/licenses/>
*/
/**
* @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"
#include "gnunet/gnunet_util_lib.h"
#include "taler_signatures.h"
#include "taler_exchangedb_lib.h"
#define RSA_KEY_SIZE 1024
#define EXITIF(cond) \
do { \
if (cond) { GNUNET_break (0); goto EXITIF_exit; } \
} while (0)
/**
* @brief Iterator called on denomination key.
*
* @param cls closure with expected DKI
* @param dki the denomination key
* @param alias coin alias
* @return #GNUNET_OK to continue to iterate,
* #GNUNET_NO to stop iteration with no error,
* #GNUNET_SYSERR to abort iteration with error!
*/
static int
dki_iter (void *cls,
const char *alias,
const struct TALER_EXCHANGEDB_DenominationKey *dki)
{
const struct TALER_EXCHANGEDB_DenominationKey *exp = cls;
(void) alias;
if (0 != GNUNET_memcmp (&exp->issue,
&dki->issue))
{
GNUNET_break (0);
return GNUNET_SYSERR;
}
if (0 !=
GNUNET_CRYPTO_rsa_private_key_cmp (exp->denom_priv.rsa_private_key,
dki->denom_priv.rsa_private_key))
{
GNUNET_break (0);
return GNUNET_SYSERR;
}
if (0 !=
GNUNET_CRYPTO_rsa_public_key_cmp (exp->denom_pub.rsa_public_key,
dki->denom_pub.rsa_public_key))
{
GNUNET_break (0);
return GNUNET_SYSERR;
}
return GNUNET_OK;
}
/**
* @brief Iterator called on revoked denomination key.
*
* @param cls closure with expected DKI
* @param denom_hash hash of the revoked denomination key
* @param revocation_master_sig non-NULL if @a dki was revoked
* @return #GNUNET_OK to continue to iterate,
* #GNUNET_NO to stop iteration with no error,
* #GNUNET_SYSERR to abort iteration with error!
*/
static int
dki_iter_revoked (void *cls,
const struct GNUNET_HashCode *denom_hash,
const struct TALER_MasterSignatureP *revocation_master_sig)
{
const struct TALER_EXCHANGEDB_DenominationKey *exp = cls;
if (NULL == revocation_master_sig)
{
GNUNET_break (0);
return GNUNET_SYSERR;
}
if (0 != GNUNET_memcmp (denom_hash,
&exp->issue.properties.denom_hash))
{
GNUNET_break (0);
return GNUNET_SYSERR;
}
return GNUNET_OK;
}
int
main (int argc,
const char *const argv[])
{
struct TALER_EXCHANGEDB_DenominationKey dki;
void *enc;
size_t enc_size;
struct TALER_EXCHANGEDB_DenominationKey dki_read;
struct TALER_MasterPrivateKeyP master_priv;
struct TALER_MasterPublicKeyP master_pub;
void *enc_read;
size_t enc_read_size;
char *tmpfile;
char *tmpdir;
char *revdir;
int ret;
struct GNUNET_TIME_Absolute start;
(void) argc;
(void) argv;
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_eddsa_key_create (&master_priv.eddsa_priv);
GNUNET_CRYPTO_eddsa_key_get_public (&master_priv.eddsa_priv,
&master_pub.eddsa_pub);
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
&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 == (tmpdir = GNUNET_DISK_mkdtemp ("test_exchangedb_dki")));
start = GNUNET_TIME_absolute_ntoh (dki.issue.properties.start);
GNUNET_asprintf (&tmpfile,
"%s/%s/%s/%llu",
tmpdir,
TALER_EXCHANGEDB_DIR_DENOMINATION_KEYS,
"cur-unit-uuid",
(unsigned long long) start.abs_value_us);
GNUNET_asprintf (&revdir,
"%s/revocations/",
tmpdir);
EXITIF (GNUNET_OK !=
TALER_EXCHANGEDB_denomination_key_write (tmpfile,
&dki));
EXITIF (GNUNET_OK !=
TALER_EXCHANGEDB_denomination_key_read (tmpfile,
&dki_read));
EXITIF (1 !=
TALER_EXCHANGEDB_denomination_keys_iterate (tmpdir,
&dki_iter,
&dki));
EXITIF (GNUNET_OK !=
TALER_EXCHANGEDB_denomination_key_revoke (revdir,
&dki.issue.properties.
denom_hash,
&master_priv));
EXITIF (1 !=
TALER_EXCHANGEDB_revocations_iterate (revdir,
&master_pub,
&dki_iter_revoked,
&dki));
GNUNET_free (revdir);
enc_read_size = GNUNET_CRYPTO_rsa_private_key_encode (
dki_read.denom_priv.rsa_private_key,
&enc_read);
EXITIF (enc_size != enc_read_size);
EXITIF (0 != memcmp (enc,
enc_read,
enc_size));
ret = 0;
EXITIF_exit:
GNUNET_free (enc);
GNUNET_free (tmpfile);
if (NULL != tmpdir)
{
(void) GNUNET_DISK_directory_remove (tmpdir);
GNUNET_free (tmpdir);
}
GNUNET_free (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);
if (NULL != dki_read.denom_pub.rsa_public_key)
GNUNET_CRYPTO_rsa_public_key_free (dki_read.denom_pub.rsa_public_key);
return ret;
}

View File

@ -1,153 +0,0 @@
/*
This file is part of TALER
Copyright (C) 2017 Taler Systems SA
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, see <http://www.gnu.org/licenses/>
*/
/**
* @file exchangedb/test_exchangedb_fees.c
* @brief test cases for functions in exchangedb/exchangedb_fees.c
* @author Christian Grothoff
*/
#include "platform.h"
#include "gnunet/gnunet_util_lib.h"
#include "taler_signatures.h"
#include "taler_exchangedb_lib.h"
/**
* Sign @a af with @a priv
*
* @param[in|out] af fee structure to sign
* @param priv private key to use for signing
*/
static void
sign_af (struct TALER_EXCHANGEDB_AggregateFees *af,
const struct GNUNET_CRYPTO_EddsaPrivateKey *priv)
{
struct TALER_MasterWireFeePS wf;
TALER_EXCHANGEDB_fees_2_wf ("test",
af,
&wf);
GNUNET_CRYPTO_eddsa_sign (priv,
&wf,
&af->master_sig.eddsa_signature);
}
int
main (int argc,
const char *const argv[])
{
struct GNUNET_CONFIGURATION_Handle *cfg;
struct TALER_EXCHANGEDB_AggregateFees *af;
struct TALER_EXCHANGEDB_AggregateFees *n;
struct TALER_MasterPublicKeyP master_pub;
struct GNUNET_CRYPTO_EddsaPrivateKey priv;
char *tmpdir;
char *tmpfile = NULL;
int ret;
unsigned int year;
(void) argc;
(void) argv;
GNUNET_log_setup ("test-exchangedb-fees",
"WARNING",
NULL);
tmpdir = GNUNET_DISK_mkdtemp ("test_exchangedb_fees");
if (NULL == tmpdir)
return 77; /* skip test */
GNUNET_CRYPTO_eddsa_key_create (&priv);
GNUNET_CRYPTO_eddsa_key_get_public (&priv,
&master_pub.eddsa_pub);
cfg = GNUNET_CONFIGURATION_create ();
GNUNET_CONFIGURATION_set_value_string (cfg,
"exchangedb",
"WIREFEE_BASE_DIR",
tmpdir);
GNUNET_asprintf (&tmpfile,
"%s/%s.fee",
tmpdir,
"test");
ret = 0;
af = GNUNET_new (struct TALER_EXCHANGEDB_AggregateFees);
year = GNUNET_TIME_get_current_year ();
af->start_date = GNUNET_TIME_year_to_time (year);
af->end_date = GNUNET_TIME_year_to_time (year + 1);
GNUNET_assert (GNUNET_OK ==
TALER_string_to_amount ("EUR:1.0",
&af->wire_fee));
GNUNET_assert (GNUNET_OK ==
TALER_string_to_amount ("EUR:1.0",
&af->closing_fee));
sign_af (af,
&priv);
n = GNUNET_new (struct TALER_EXCHANGEDB_AggregateFees);
n->start_date = GNUNET_TIME_year_to_time (year + 1);
n->end_date = GNUNET_TIME_year_to_time (year + 2);
GNUNET_assert (GNUNET_OK ==
TALER_string_to_amount ("EUR:0.1",
&n->wire_fee));
GNUNET_assert (GNUNET_OK ==
TALER_string_to_amount ("EUR:0.1",
&n->closing_fee));
sign_af (n,
&priv);
af->next = n;
if (GNUNET_OK !=
TALER_EXCHANGEDB_fees_write (tmpfile,
"test",
af))
{
GNUNET_break (0);
ret = 1;
}
TALER_EXCHANGEDB_fees_free (af);
GNUNET_free (tmpfile);
af = TALER_EXCHANGEDB_fees_read (cfg,
"test");
if (NULL == af)
{
GNUNET_break (0);
ret = 1;
}
else
{
for (struct TALER_EXCHANGEDB_AggregateFees *p = af;
NULL != p;
p = p->next)
{
struct TALER_MasterWireFeePS wf;
TALER_EXCHANGEDB_fees_2_wf ("test",
p,
&wf);
if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_WIRE_FEES,
&wf,
&p->master_sig.eddsa_signature,
&master_pub.eddsa_pub))
{
GNUNET_break (0);
ret = 1;
}
}
TALER_EXCHANGEDB_fees_free (af);
}
(void) GNUNET_DISK_directory_remove (tmpdir);
GNUNET_free (tmpdir);
GNUNET_CONFIGURATION_destroy (cfg);
return ret;
}

View File

@ -1,99 +0,0 @@
/*
This file is part of TALER
Copyright (C) 2016 Taler Systems SA
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, see <http://www.gnu.org/licenses/>
*/
/**
* @file exchangedb/test_exchangedb_signkeys.c
* @brief test cases for some functions in exchangedb/exchangedb_signkeys.c
* @author Christian Grothoff
*/
#include "platform.h"
#include "gnunet/gnunet_util_lib.h"
#include "taler_signatures.h"
#include "taler_exchangedb_lib.h"
#define EXITIF(cond) \
do { \
if (cond) { GNUNET_break (0); goto EXITIF_exit; } \
} while (0)
/**
* @brief Iterator over signing keys.
*
* @param cls closure
* @param filename name of the file the key came from
* @param ski the sign key
* @return #GNUNET_OK to continue to iterate,
* #GNUNET_NO to stop iteration with no error,
* #GNUNET_SYSERR to abort iteration with error!
*/
static int
ski_iter (void *cls,
const char *filename,
const struct TALER_EXCHANGEDB_PrivateSigningKeyInformationP *ski)
{
const struct TALER_EXCHANGEDB_PrivateSigningKeyInformationP *exp = cls;
(void) filename;
if (0 != GNUNET_memcmp (ski,
exp))
{
GNUNET_break (0);
return GNUNET_SYSERR;
}
return GNUNET_OK;
}
int
main (int argc,
const char *const argv[])
{
struct TALER_EXCHANGEDB_PrivateSigningKeyInformationP ski;
struct GNUNET_TIME_Absolute now;
char *tmpfile;
int ret;
(void) argc;
(void) argv;
ret = 1;
tmpfile = NULL;
GNUNET_log_setup ("test-exchangedb-signkeys",
"WARNING",
NULL);
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
&ski,
sizeof (struct
TALER_EXCHANGEDB_PrivateSigningKeyInformationP));
now = GNUNET_TIME_absolute_get ();
EXITIF (NULL == (tmpfile = GNUNET_DISK_mkdtemp ("test_exchangedb_ski")));
EXITIF (GNUNET_OK !=
TALER_EXCHANGEDB_signing_key_write (tmpfile,
now,
&ski));
EXITIF (1 !=
TALER_EXCHANGEDB_signing_keys_iterate (tmpfile,
&ski_iter,
&ski));
ret = 0;
EXITIF_exit:
if (NULL != tmpfile)
{
(void) GNUNET_DISK_directory_remove (tmpfile);
GNUNET_free (tmpfile);
}
return ret;
}

View File

@ -1,6 +1,6 @@
/*
This file is part of TALER
Copyright (C) 2014-2017 Taler Systems SA
Copyright (C) 2014-2020 Taler Systems SA
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
@ -27,250 +27,6 @@
#include "taler_exchangedb_plugin.h"
#include "taler_bank_service.h"
/**
* Subdirectroy under the exchange's base directory which contains
* the exchange's signing keys.
*/
#define TALER_EXCHANGEDB_DIR_SIGNING_KEYS "signkeys"
/**
* Subdirectory under the exchange's base directory which contains
* the exchange's denomination keys.
*/
#define TALER_EXCHANGEDB_DIR_DENOMINATION_KEYS "denomkeys"
/**
* @brief Iterator over signing keys.
*
* @param cls closure
* @param filename name of the file the key came from
* @param ski the sign key
* @return #GNUNET_OK to continue to iterate,
* #GNUNET_NO to stop iteration with no error,
* #GNUNET_SYSERR to abort iteration with error!
*/
typedef int
(*TALER_EXCHANGEDB_SigningKeyIterator)(
void *cls,
const char *filename,
const struct TALER_EXCHANGEDB_PrivateSigningKeyInformationP *ski);
/**
* 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);
/**
* 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);
/**
* @brief Iterator over denomination keys.
*
* @param cls closure
* @param alias coin alias
* @param dki the denomination key
* @return #GNUNET_OK to continue to iterate,
* #GNUNET_NO to stop iteration with no error,
* #GNUNET_SYSERR to abort iteration with error!
*/
typedef int
(*TALER_EXCHANGEDB_DenominationKeyIterator)(
void *cls,
const char *alias,
const struct TALER_EXCHANGEDB_DenominationKey *dki);
/**
* @brief Iterator over revoked denomination keys.
*
* @param cls closure
* @param denom_hash hash of the denomination public key
* @param revocation_master_sig signature showing @a denom_hash was revoked
* @return #GNUNET_OK to continue to iterate,
* #GNUNET_NO to stop iteration with no error,
* #GNUNET_SYSERR to abort iteration with error!
*/
typedef int
(*TALER_EXCHANGEDB_RevocationIterator)(
void *cls,
const struct GNUNET_HashCode *denom_hash,
const struct TALER_MasterSignatureP *revocation_master_sig);
/**
* 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);
/**
* Call @a it for each revoked denomination key found in the @a revocation_dir.
*
* @param revocation_dir base directory where revocations are stored
* @param master_pub master public key (used to check revocations)
* @param it function to call on each revoked 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_revocations_iterate (
const char *revocation_dir,
const struct TALER_MasterPublicKeyP *master_pub,
TALER_EXCHANGEDB_RevocationIterator it,
void *it_cls);
/**
* Mark the given denomination key as revoked and request the wallets
* to initiate recoup.
*
* @param revocation_dir where to write the revocation certificate
* @param denom_hash hash of the denomination key to revoke
* @param mpriv master private key to sign with
* @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure.
*/
int
TALER_EXCHANGEDB_denomination_key_revoke (
const char *revocation_dir,
const struct GNUNET_HashCode *denom_hash,
const struct TALER_MasterPrivateKeyP *mpriv);
/**
* 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_DenominationKey *dki);
/**
* 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_DenominationKey *dki);
/**
* @brief Iterator over auditor information.
*
* @param cls closure
* @param apub the auditor's public key
* @param auditor_url URL of the auditor
* @param mpub the exchange's public key (as expected by the auditor)
* @param dki_len length of @a asig and @a dki arrays
* @param asigs array of the auditor's signatures over the @a dks, of length @a dki_len
* @param dki array of denomination coin data signed by the auditor, of length @a dki_len
* @return #GNUNET_OK to continue to iterate,
* #GNUNET_NO to stop iteration with no error,
* #GNUNET_SYSERR to abort iteration with error!
*/
typedef int
(*TALER_EXCHANGEDB_AuditorIterator)(
void *cls,
const struct TALER_AuditorPublicKeyP *apub,
const char *auditor_url,
const struct TALER_MasterPublicKeyP *mpub,
unsigned int dki_len,
const struct TALER_AuditorSignatureP *asigs,
const struct TALER_DenominationKeyValidityPS *dki);
/**
* Call @a it with information for each auditor found in the
* directory with auditor information as specified in @a cfg.
*
* @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);
/**
* 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 and @a asigs arrays
* @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,
uint32_t dki_len,
const struct TALER_DenominationKeyValidityPS *dki);
/**
* Initialize the plugin.
@ -291,93 +47,6 @@ void
TALER_EXCHANGEDB_plugin_unload (struct TALER_EXCHANGEDB_Plugin *plugin);
/**
* Sorted list of fees to be paid for aggregate wire transfers.
* Sorted by @e start_date or @e end_date --- both work fine as
* the resulting order must be the same.
*/
struct TALER_EXCHANGEDB_AggregateFees
{
/**
* This is a linked list.
*/
struct TALER_EXCHANGEDB_AggregateFees *next;
/**
* Fee to be paid for wire transfers to a merchant.
*/
struct TALER_Amount wire_fee;
/**
* Fee to be paid when we close a reserve and send funds back.
*/
struct TALER_Amount closing_fee;
/**
* Time when this fee goes into effect (inclusive)
*/
struct GNUNET_TIME_Absolute start_date;
/**
* Time when this fee stops being in effect (exclusive).
*/
struct GNUNET_TIME_Absolute end_date;
/**
* Signature affirming the above fee structure.
*/
struct TALER_MasterSignatureP master_sig;
};
/**
* Read the current fee structure from disk.
*
* @param cfg configuration to use
* @param wireplugin name of the wire plugin to read fees for
* @return sorted list of aggregation fees, NULL on error
*/
struct TALER_EXCHANGEDB_AggregateFees *
TALER_EXCHANGEDB_fees_read (const struct GNUNET_CONFIGURATION_Handle *cfg,
const char *wireplugin);
/**
* Convert @a af to @a wf.
*
* @param wiremethod name of the wire method the fees are for
* @param[in,out] af aggregate fees, host format (updated to round time)
* @param[out] wf aggregate fees, disk / signature format
*/
void
TALER_EXCHANGEDB_fees_2_wf (const char *wiremethod,
struct TALER_EXCHANGEDB_AggregateFees *af,
struct TALER_MasterWireFeePS *wf);
/**
* Write given fee structure to disk.
*
* @param filename where to write the fees
* @param wireplugin name of the plugin for which we write the fees
* @param af fee structure to write
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
*/
int
TALER_EXCHANGEDB_fees_write (const char *filename,
const char *wireplugin,
struct TALER_EXCHANGEDB_AggregateFees *af);
/**
* Free @a af data structure
*
* @param af list to free
*/
void
TALER_EXCHANGEDB_fees_free (struct TALER_EXCHANGEDB_AggregateFees *af);
/**
* Information about an account from the configuration.
*/
@ -485,11 +154,6 @@ struct TALER_EXCHANGEDB_WireAccount
*/
struct TALER_BANK_AuthenticationData auth;
/**
* Wire transfer fee structure.
*/
struct TALER_EXCHANGEDB_AggregateFees *af;
/**
* Name of the section that configures this account.
*/
@ -503,24 +167,6 @@ struct TALER_EXCHANGEDB_WireAccount
};
/**
* Update wire transfer fee data structure in @a wa.
*
* @param cfg configuration to use
* @param db_plugin database plugin to use
* @param wa wire account data structure to update
* @param now timestamp to update fees to
* @param session DB session to use
* @return fee valid at @a now, or NULL if unknown
*/
struct TALER_EXCHANGEDB_AggregateFees *
TALER_EXCHANGEDB_update_fees (const struct GNUNET_CONFIGURATION_Handle *cfg,
struct TALER_EXCHANGEDB_Plugin *db_plugin,
struct TALER_EXCHANGEDB_WireAccount *wa,
struct GNUNET_TIME_Absolute now,
struct TALER_EXCHANGEDB_Session *session);
/**
* Find the wire plugin for the given payto:// URL.
* Only useful after the accounts have been loaded

View File

@ -206,15 +206,19 @@ TALER_TESTING_cleanup_files_cfg (void *cls,
/**
* Run `taler-exchange-keyup`.
* Run `taler-exchange-offline`.
*
* @param config_filename configuration file to use
* @param output_filename where to write the output for the auditor
* @param payto_uri bank account to enable, can be NULL
* @param auditor_pub public key of auditor to enable, can be NULL
* @param auditor_url URL of auditor to enable, can be NULL
* @return #GNUNET_OK on success
*/
int
TALER_TESTING_run_keyup (const char *config_filename,
const char *output_filename);
TALER_TESTING_run_exchange_offline (const char *config_filename,
const char *payto_uri,
const char *auditor_pub,
const char *auditor_url);
/**
@ -238,21 +242,13 @@ TALER_TESTING_exchange_db_reset (const char *config_filename);
/**
* Run `taler-auditor-sign`.
* Run `taler-auditor-offline` tool.
*
* @param config_filename configuration file to use
* @param exchange_master_pub master public key of the exchange
* @param auditor_base_url what is the base URL of the auditor
* @param signdata_in where is the information from taler-exchange-keyup
* @param signdata_out where to write the output for the exchange
* @return #GNUNET_OK on success
*/
int
TALER_TESTING_run_auditor_sign (const char *config_filename,
const char *exchange_master_pub,
const char *auditor_base_url,
const char *signdata_in,
const char *signdata_out);
TALER_TESTING_run_auditor_offline (const char *config_filename);
/**
@ -1220,18 +1216,6 @@ TALER_TESTING_cmd_exec_transfer (const char *label,
const char *config_filename);
/**
* Make a "auditor sign" CMD.
*
* @param label command label
* @param config_filename configuration filename
* @return the command.
*/
struct TALER_TESTING_Command
TALER_TESTING_cmd_exec_auditor_sign (const char *label,
const char *config_filename);
/**
* Create a withdraw command, letting the caller specify
* the desired amount as string.

View File

@ -54,7 +54,6 @@ libtalertesting_la_SOURCES = \
testing_api_cmd_deposit.c \
testing_api_cmd_deposits_get.c \
testing_api_cmd_exec_aggregator.c \
testing_api_cmd_exec_auditor-sign.c \
testing_api_cmd_exec_closer.c \
testing_api_cmd_exec_transfer.c \
testing_api_cmd_exec_wirewatch.c \

View File

@ -1,232 +0,0 @@
/*
This file is part of TALER
Copyright (C) 2018 Taler Systems SA
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,
see <http://www.gnu.org/licenses/>
*/
/**
* @file testing/testing_api_cmd_exec_auditor-sign.c
* @brief run the taler-exchange-aggregator command
* @author Marcello Stanisci
*/
#include "platform.h"
#include "taler_json_lib.h"
#include <gnunet/gnunet_curl_lib.h>
#include "taler_signatures.h"
#include "taler_testing_lib.h"
/**
* State for a "auditor sign" CMD.
*/
struct AuditorSignState
{
/**
* Handle to the process making the signature.
*/
struct GNUNET_OS_Process *auditor_sign_proc;
/**
* Configuration file used by the command.
*/
const char *config_filename;
/**
* File name of signed blob.
*/
char *signed_keys_out;
};
/**
* Run the command; calls the `taler-auditor-sign' program.
*
* @param cls closure.
* @param cmd the command.
* @param is interpreter state.
*/
static void
auditor_sign_run (void *cls,
const struct TALER_TESTING_Command *cmd,
struct TALER_TESTING_Interpreter *is)
{
struct AuditorSignState *ass = cls;
struct GNUNET_CONFIGURATION_Handle *cfg;
char *test_home_dir;
char *exchange_master_pub;
struct GNUNET_TIME_Absolute now;
(void) cmd;
cfg = GNUNET_CONFIGURATION_create ();
if (GNUNET_OK != GNUNET_CONFIGURATION_load
(cfg, ass->config_filename))
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (is);
return;
}
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_filename (cfg,
"paths",
"TALER_TEST_HOME",
&test_home_dir))
{
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
"paths",
"TALER_TEST_HOME");
GNUNET_CONFIGURATION_destroy (cfg);
GNUNET_break (0);
TALER_TESTING_interpreter_fail (is);
return;
}
now = GNUNET_TIME_absolute_get ();
GNUNET_asprintf
(&ass->signed_keys_out,
"%s/.local/share/taler/auditors/auditor-%llu.out",
test_home_dir,
(unsigned long long) now.abs_value_us);
GNUNET_free (test_home_dir);
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_string (cfg,
"exchange",
"MASTER_PUBLIC_KEY",
&exchange_master_pub))
{
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
"exchange",
"MASTER_PUBLIC_KEY");
GNUNET_CONFIGURATION_destroy (cfg);
GNUNET_break (0);
TALER_TESTING_interpreter_fail (is);
return;
}
GNUNET_CONFIGURATION_destroy (cfg);
ass->auditor_sign_proc
= GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ALL,
NULL, NULL, NULL,
"taler-auditor-sign",
"taler-auditor-sign",
"-c", ass->config_filename,
"-u", "http://auditor/",
"-m", exchange_master_pub,
"-r", "auditor.in",
"-o", ass->signed_keys_out,
NULL);
GNUNET_free (exchange_master_pub);
if (NULL == ass->auditor_sign_proc)
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (is);
return;
}
TALER_TESTING_wait_for_sigchld (is);
}
/**
* Free the state of a "auditor sign" CMD, and possibly
* kill its process if it did not terminate correctly.
*
* @param cls closure.
* @param cmd the command being freed.
*/
static void
auditor_sign_cleanup (void *cls,
const struct TALER_TESTING_Command *cmd)
{
struct AuditorSignState *ass = cls;
(void) cmd;
if (NULL != ass->auditor_sign_proc)
{
GNUNET_break (0 == GNUNET_OS_process_kill
(ass->auditor_sign_proc, SIGKILL));
GNUNET_OS_process_wait (ass->auditor_sign_proc);
GNUNET_OS_process_destroy (ass->auditor_sign_proc);
ass->auditor_sign_proc = NULL;
}
GNUNET_free (ass->signed_keys_out);
GNUNET_free (ass);
}
/**
* Offer "auditor sign" CMD internal data to other commands.
*
* @param cls closure.
* @param[out] ret result.
* @param trait name of the trait.
* @param index index number of the object to offer.
* @return #GNUNET_OK on success.
*/
static int
auditor_sign_traits (void *cls,
const void **ret,
const char *trait,
unsigned int index)
{
struct AuditorSignState *ass = cls;
struct TALER_TESTING_Trait traits[] = {
TALER_TESTING_make_trait_process (0, &ass->auditor_sign_proc),
TALER_TESTING_trait_end ()
};
return TALER_TESTING_get_trait (traits,
ret,
trait,
index);
}
/**
* Make a "auditor sign" CMD.
*
* @param label command label
* @param config_filename configuration filename
*
* @return the command.
*/
struct TALER_TESTING_Command
TALER_TESTING_cmd_exec_auditor_sign (const char *label,
const char *config_filename)
{
struct AuditorSignState *ass;
ass = GNUNET_new (struct AuditorSignState);
ass->config_filename = config_filename;
{
struct TALER_TESTING_Command cmd = {
.cls = ass,
.label = label,
.run = &auditor_sign_run,
.cleanup = &auditor_sign_cleanup,
.traits = &auditor_sign_traits
};
return cmd;
}
}
/* end of testing_api_cmd_exec_auditor-sign.c */