2015-01-08 18:37:20 +01:00
|
|
|
/*
|
|
|
|
This file is part of TALER
|
2015-02-08 00:16:22 +01:00
|
|
|
Copyright (C) 2014 Christian Grothoff (and other contributing authors)
|
2015-01-08 18:37:20 +01:00
|
|
|
|
|
|
|
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 taler-mint-keyup.c
|
|
|
|
* @brief Update the mint's keys for coins and signatures,
|
|
|
|
* using the mint's offline master key.
|
|
|
|
* @author Florian Dold
|
|
|
|
* @author Benedikt Mueller
|
|
|
|
*/
|
|
|
|
#include <platform.h>
|
|
|
|
#include <gnunet/gnunet_util_lib.h>
|
|
|
|
#include "taler_util.h"
|
2015-01-28 15:03:47 +01:00
|
|
|
#include "key_io.h"
|
2015-01-08 18:37:20 +01:00
|
|
|
|
2015-01-27 14:55:05 +01:00
|
|
|
/**
|
|
|
|
* FIXME: allow user to specify (within reason).
|
|
|
|
*/
|
|
|
|
#define RSA_KEYSIZE 2048
|
|
|
|
|
2015-03-15 22:33:28 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
2015-01-08 18:37:20 +01:00
|
|
|
#define HASH_CUTOFF 20
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Macro to round microseconds to seconds in GNUNET_TIME_* structs.
|
|
|
|
*/
|
|
|
|
#define ROUND_TO_SECS(name,us_field) name.us_field -= name.us_field % (1000 * 1000);
|
|
|
|
|
|
|
|
|
|
|
|
GNUNET_NETWORK_STRUCT_BEGIN
|
|
|
|
|
2015-03-15 22:33:28 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
2015-01-08 18:37:20 +01:00
|
|
|
struct CoinTypeNBO
|
|
|
|
{
|
2015-03-15 22:33:28 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
2015-01-08 18:37:20 +01:00
|
|
|
struct GNUNET_TIME_RelativeNBO duration_spend;
|
2015-03-15 22:33:28 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
2015-01-08 18:37:20 +01:00
|
|
|
struct GNUNET_TIME_RelativeNBO duration_withdraw;
|
2015-03-15 22:33:28 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
2015-01-08 18:37:20 +01:00
|
|
|
struct TALER_AmountNBO value;
|
2015-03-15 22:33:28 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
2015-01-08 18:37:20 +01:00
|
|
|
struct TALER_AmountNBO fee_withdraw;
|
2015-03-15 22:33:28 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
2015-01-08 18:37:20 +01:00
|
|
|
struct TALER_AmountNBO fee_deposit;
|
2015-03-15 22:33:28 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
2015-01-08 18:37:20 +01:00
|
|
|
struct TALER_AmountNBO fee_refresh;
|
|
|
|
};
|
|
|
|
|
|
|
|
GNUNET_NETWORK_STRUCT_END
|
|
|
|
|
2015-03-15 22:33:28 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
2015-01-08 18:37:20 +01:00
|
|
|
struct CoinTypeParams
|
|
|
|
{
|
2015-03-15 22:33:28 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
2015-01-08 18:37:20 +01:00
|
|
|
struct GNUNET_TIME_Relative duration_spend;
|
2015-03-15 22:33:28 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
2015-01-08 18:37:20 +01:00
|
|
|
struct GNUNET_TIME_Relative duration_withdraw;
|
2015-03-15 22:33:28 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
2015-01-08 18:37:20 +01:00
|
|
|
struct GNUNET_TIME_Relative duration_overlap;
|
2015-03-15 22:33:28 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
2015-01-08 18:37:20 +01:00
|
|
|
struct TALER_Amount value;
|
2015-03-15 22:33:28 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
2015-01-08 18:37:20 +01:00
|
|
|
struct TALER_Amount fee_withdraw;
|
2015-03-15 22:33:28 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
2015-01-08 18:37:20 +01:00
|
|
|
struct TALER_Amount fee_deposit;
|
2015-03-15 22:33:28 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
2015-01-08 18:37:20 +01:00
|
|
|
struct TALER_Amount fee_refresh;
|
2015-03-15 22:33:28 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
2015-01-08 18:37:20 +01:00
|
|
|
struct GNUNET_TIME_Absolute anchor;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Filename of the master private key.
|
|
|
|
*/
|
|
|
|
static char *masterkeyfile;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Director of the mint, containing the keys.
|
|
|
|
*/
|
|
|
|
static char *mintdir;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Time to pretend when the key update is executed.
|
|
|
|
*/
|
|
|
|
static char *pretend_time_str;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handle to the mint's configuration
|
|
|
|
*/
|
|
|
|
static struct GNUNET_CONFIGURATION_Handle *kcfg;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Time when the key update is executed. Either the actual current time, or a
|
|
|
|
* pretended time.
|
|
|
|
*/
|
|
|
|
static struct GNUNET_TIME_Absolute now;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Master private key of the mint.
|
|
|
|
*/
|
|
|
|
static struct GNUNET_CRYPTO_EddsaPrivateKey *master_priv;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Master public key of the mint.
|
|
|
|
*/
|
|
|
|
static struct GNUNET_CRYPTO_EddsaPublicKey *master_pub;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Until what time do we provide keys?
|
|
|
|
*/
|
|
|
|
static struct GNUNET_TIME_Absolute lookahead_sign_stamp;
|
|
|
|
|
|
|
|
|
2015-03-15 22:33:28 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param section
|
|
|
|
* @param option
|
|
|
|
* @param denom
|
|
|
|
* @return
|
|
|
|
*/
|
2015-01-26 12:22:26 +01:00
|
|
|
static int
|
2015-03-15 22:33:28 +01:00
|
|
|
config_get_denom (const char *section,
|
|
|
|
const char *option,
|
|
|
|
struct TALER_Amount *denom)
|
2015-01-08 18:37:20 +01:00
|
|
|
{
|
|
|
|
char *str;
|
2015-03-15 22:33:28 +01:00
|
|
|
|
|
|
|
if (GNUNET_OK !=
|
|
|
|
GNUNET_CONFIGURATION_get_value_string (kcfg,
|
|
|
|
section,
|
|
|
|
option,
|
|
|
|
&str))
|
2015-01-08 18:37:20 +01:00
|
|
|
return GNUNET_NO;
|
2015-03-15 22:33:28 +01:00
|
|
|
if (GNUNET_OK != TALER_string_to_amount (str,
|
|
|
|
denom))
|
2015-01-08 18:37:20 +01:00
|
|
|
return GNUNET_SYSERR;
|
|
|
|
return GNUNET_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-03-15 22:33:28 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @return
|
|
|
|
*/
|
2015-01-26 12:22:26 +01:00
|
|
|
static char *
|
2015-01-08 18:37:20 +01:00
|
|
|
get_signkey_dir ()
|
|
|
|
{
|
|
|
|
char *dir;
|
2015-03-15 22:33:28 +01:00
|
|
|
|
|
|
|
GNUNET_asprintf (&dir,
|
|
|
|
"%s" DIR_SEPARATOR_STR DIR_SIGNKEYS,
|
|
|
|
mintdir);
|
2015-01-08 18:37:20 +01:00
|
|
|
return dir;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-03-15 22:33:28 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param start
|
|
|
|
* @return
|
|
|
|
*/
|
2015-01-26 12:22:26 +01:00
|
|
|
static char *
|
2015-01-08 18:37:20 +01:00
|
|
|
get_signkey_file (struct GNUNET_TIME_Absolute start)
|
|
|
|
{
|
|
|
|
char *dir;
|
2015-03-15 22:33:28 +01:00
|
|
|
|
|
|
|
GNUNET_asprintf (&dir,
|
|
|
|
"%s" DIR_SEPARATOR_STR DIR_SIGNKEYS DIR_SEPARATOR_STR "%llu",
|
|
|
|
mintdir,
|
|
|
|
(unsigned long long) start.abs_value_us);
|
2015-01-08 18:37:20 +01:00
|
|
|
return dir;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Hash the data defining the coin type.
|
|
|
|
* Exclude information that may not be the same for all
|
|
|
|
* instances of the coin type (i.e. the anchor, overlap).
|
2015-03-15 22:33:28 +01:00
|
|
|
*
|
|
|
|
* @param p
|
|
|
|
* @param hash
|
2015-01-08 18:37:20 +01:00
|
|
|
*/
|
2015-01-26 12:22:26 +01:00
|
|
|
static void
|
2015-03-15 22:33:28 +01:00
|
|
|
hash_coin_type (const struct CoinTypeParams *p,
|
|
|
|
struct GNUNET_HashCode *hash)
|
2015-01-08 18:37:20 +01:00
|
|
|
{
|
|
|
|
struct CoinTypeNBO p_nbo;
|
|
|
|
|
2015-03-15 22:33:28 +01:00
|
|
|
memset (&p_nbo,
|
|
|
|
0,
|
|
|
|
sizeof (struct CoinTypeNBO));
|
2015-01-08 18:37:20 +01:00
|
|
|
|
|
|
|
p_nbo.duration_spend = GNUNET_TIME_relative_hton (p->duration_spend);
|
|
|
|
p_nbo.duration_withdraw = GNUNET_TIME_relative_hton (p->duration_withdraw);
|
|
|
|
p_nbo.value = TALER_amount_hton (p->value);
|
|
|
|
p_nbo.fee_withdraw = TALER_amount_hton (p->fee_withdraw);
|
|
|
|
p_nbo.fee_deposit = TALER_amount_hton (p->fee_deposit);
|
|
|
|
p_nbo.fee_refresh = TALER_amount_hton (p->fee_refresh);
|
|
|
|
|
2015-03-15 22:33:28 +01:00
|
|
|
GNUNET_CRYPTO_hash (&p_nbo,
|
|
|
|
sizeof (struct CoinTypeNBO),
|
|
|
|
hash);
|
2015-01-08 18:37:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-03-15 22:33:28 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param p
|
|
|
|
* @return
|
|
|
|
*/
|
2015-01-08 18:37:20 +01:00
|
|
|
static const char *
|
|
|
|
get_cointype_dir (const struct CoinTypeParams *p)
|
|
|
|
{
|
|
|
|
static char dir[4096];
|
|
|
|
struct GNUNET_HashCode hash;
|
|
|
|
char *hash_str;
|
|
|
|
char *val_str;
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
hash_coin_type (p, &hash);
|
2015-01-28 20:31:28 +01:00
|
|
|
hash_str = GNUNET_STRINGS_data_to_string_alloc (&hash,
|
|
|
|
sizeof (struct GNUNET_HashCode));
|
2015-01-08 18:37:20 +01:00
|
|
|
GNUNET_assert (HASH_CUTOFF <= strlen (hash_str) + 1);
|
|
|
|
GNUNET_assert (NULL != hash_str);
|
|
|
|
hash_str[HASH_CUTOFF] = 0;
|
|
|
|
|
|
|
|
val_str = TALER_amount_to_string (p->value);
|
|
|
|
for (i = 0; i < strlen (val_str); i++)
|
|
|
|
if (':' == val_str[i] || '.' == val_str[i])
|
|
|
|
val_str[i] = '_';
|
|
|
|
|
2015-03-15 22:33:28 +01:00
|
|
|
GNUNET_snprintf (dir,
|
|
|
|
sizeof (dir),
|
|
|
|
"%s" DIR_SEPARATOR_STR DIR_DENOMKEYS DIR_SEPARATOR_STR "%s-%s",
|
|
|
|
mintdir,
|
|
|
|
val_str,
|
|
|
|
hash_str);
|
2015-01-08 18:37:20 +01:00
|
|
|
GNUNET_free (hash_str);
|
|
|
|
return dir;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-03-15 22:33:28 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param p
|
|
|
|
* @param start
|
|
|
|
* @return
|
|
|
|
*/
|
2015-01-08 18:37:20 +01:00
|
|
|
static const char *
|
|
|
|
get_cointype_file (struct CoinTypeParams *p,
|
|
|
|
struct GNUNET_TIME_Absolute start)
|
|
|
|
{
|
|
|
|
const char *dir;
|
|
|
|
static char filename[4096];
|
2015-03-15 22:33:28 +01:00
|
|
|
|
2015-01-08 18:37:20 +01:00
|
|
|
dir = get_cointype_dir (p);
|
2015-03-15 22:33:28 +01:00
|
|
|
GNUNET_snprintf (filename,
|
|
|
|
sizeof (filename),
|
|
|
|
"%s" DIR_SEPARATOR_STR "%llu",
|
|
|
|
dir,
|
|
|
|
(unsigned long long) start.abs_value_us);
|
2015-01-08 18:37:20 +01:00
|
|
|
return filename;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the latest key file from the past.
|
|
|
|
*
|
|
|
|
* @param cls closure
|
|
|
|
* @param filename complete filename (absolute path)
|
|
|
|
* @return #GNUNET_OK to continue to iterate,
|
|
|
|
* #GNUNET_NO to stop iteration with no error,
|
|
|
|
* #GNUNET_SYSERR to abort iteration with error!
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
get_anchor_iter (void *cls,
|
|
|
|
const char *filename)
|
|
|
|
{
|
|
|
|
struct GNUNET_TIME_Absolute *anchor = cls;
|
2015-03-15 22:33:28 +01:00
|
|
|
struct GNUNET_TIME_Absolute stamp;
|
2015-01-08 18:37:20 +01:00
|
|
|
const char *base;
|
|
|
|
char *end = NULL;
|
|
|
|
|
|
|
|
base = GNUNET_STRINGS_get_short_name (filename);
|
2015-03-15 22:33:28 +01:00
|
|
|
stamp.abs_value_us = strtol (base,
|
|
|
|
&end,
|
|
|
|
10);
|
2015-01-08 18:37:20 +01:00
|
|
|
|
|
|
|
if ((NULL == end) || (0 != *end))
|
|
|
|
{
|
2015-03-15 22:33:28 +01:00
|
|
|
fprintf(stderr,
|
|
|
|
"Ignoring unexpected file '%s'.\n",
|
|
|
|
filename);
|
2015-01-08 18:37:20 +01:00
|
|
|
return GNUNET_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: check if it's actually a valid key file
|
|
|
|
|
2015-03-15 22:33:28 +01:00
|
|
|
if ( (stamp.abs_value_us <= now.abs_value_us) &&
|
|
|
|
( stamp.abs_value_us > anchor->abs_value_us) )
|
2015-01-08 18:37:20 +01:00
|
|
|
*anchor = stamp;
|
|
|
|
|
|
|
|
return GNUNET_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the timestamp where the first new key should be generated.
|
|
|
|
* Relies on correctly named key files.
|
|
|
|
*
|
|
|
|
* @param dir directory with the signed stuff
|
|
|
|
* @param duration how long is one key valid?
|
|
|
|
* @param overlap what's the overlap between the keys validity period?
|
|
|
|
* @param[out] anchor the timestamp where the first new key should be generated
|
|
|
|
*/
|
2015-01-26 12:22:26 +01:00
|
|
|
static void
|
2015-01-08 18:37:20 +01:00
|
|
|
get_anchor (const char *dir,
|
|
|
|
struct GNUNET_TIME_Relative duration,
|
|
|
|
struct GNUNET_TIME_Relative overlap,
|
|
|
|
struct GNUNET_TIME_Absolute *anchor)
|
|
|
|
{
|
|
|
|
GNUNET_assert (0 == duration.rel_value_us % 1000000);
|
|
|
|
GNUNET_assert (0 == overlap.rel_value_us % 1000000);
|
2015-03-15 22:33:28 +01:00
|
|
|
if (GNUNET_YES !=
|
|
|
|
GNUNET_DISK_directory_test (dir, GNUNET_YES))
|
2015-01-08 18:37:20 +01:00
|
|
|
{
|
|
|
|
*anchor = now;
|
2015-03-15 22:33:28 +01:00
|
|
|
fprintf (stderr,
|
|
|
|
"Cannot look for anchor (%s)\n",
|
|
|
|
dir);
|
2015-01-08 18:37:20 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
*anchor = GNUNET_TIME_UNIT_ZERO_ABS;
|
2015-03-15 22:33:28 +01:00
|
|
|
if (-1 ==
|
|
|
|
GNUNET_DISK_directory_scan (dir,
|
|
|
|
&get_anchor_iter,
|
|
|
|
anchor))
|
2015-01-08 18:37:20 +01:00
|
|
|
{
|
|
|
|
*anchor = now;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-03-15 22:33:28 +01:00
|
|
|
if ((GNUNET_TIME_absolute_add (*anchor,
|
|
|
|
duration)).abs_value_us < now.abs_value_us)
|
2015-01-08 18:37:20 +01:00
|
|
|
{
|
|
|
|
// there's no good anchor, start from now
|
|
|
|
// (existing keys are too old)
|
|
|
|
*anchor = now;
|
|
|
|
}
|
|
|
|
else if (anchor->abs_value_us != now.abs_value_us)
|
|
|
|
{
|
|
|
|
// we have a good anchor
|
|
|
|
*anchor = GNUNET_TIME_absolute_add (*anchor, duration);
|
|
|
|
*anchor = GNUNET_TIME_absolute_subtract (*anchor, overlap);
|
|
|
|
}
|
|
|
|
// anchor is now the stamp where we need to create a new key
|
|
|
|
}
|
|
|
|
|
2015-01-26 12:22:26 +01:00
|
|
|
|
2015-03-15 22:33:28 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param start
|
|
|
|
* @param duration
|
|
|
|
* @param pi
|
|
|
|
*/
|
2015-01-08 18:37:20 +01:00
|
|
|
static void
|
2015-01-09 18:18:59 +01:00
|
|
|
create_signkey_issue_priv (struct GNUNET_TIME_Absolute start,
|
|
|
|
struct GNUNET_TIME_Relative duration,
|
|
|
|
struct TALER_MINT_SignKeyIssuePriv *pi)
|
2015-01-08 18:37:20 +01:00
|
|
|
{
|
|
|
|
struct GNUNET_CRYPTO_EddsaPrivateKey *priv;
|
2015-01-09 18:18:59 +01:00
|
|
|
struct TALER_MINT_SignKeyIssue *issue = &pi->issue;
|
2015-01-08 18:37:20 +01:00
|
|
|
|
|
|
|
priv = GNUNET_CRYPTO_eddsa_key_create ();
|
2015-01-09 18:18:59 +01:00
|
|
|
pi->signkey_priv = *priv;
|
2015-01-08 18:37:20 +01:00
|
|
|
GNUNET_free (priv);
|
|
|
|
issue->master_pub = *master_pub;
|
|
|
|
issue->start = GNUNET_TIME_absolute_hton (start);
|
2015-03-15 22:33:28 +01:00
|
|
|
issue->expire = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_add (start,
|
|
|
|
duration));
|
2015-01-08 18:37:20 +01:00
|
|
|
|
2015-03-15 22:33:28 +01:00
|
|
|
GNUNET_CRYPTO_eddsa_key_get_public (&pi->signkey_priv,
|
|
|
|
&issue->signkey_pub);
|
2015-01-08 18:37:20 +01:00
|
|
|
|
|
|
|
issue->purpose.purpose = htonl (TALER_SIGNATURE_MASTER_SIGNKEY);
|
2015-03-15 22:33:28 +01:00
|
|
|
issue->purpose.size = htonl (sizeof (struct TALER_MINT_SignKeyIssue) -
|
|
|
|
offsetof (struct TALER_MINT_SignKeyIssue,
|
|
|
|
purpose));
|
2015-01-08 18:37:20 +01:00
|
|
|
|
2015-03-09 11:24:35 +01:00
|
|
|
GNUNET_assert (GNUNET_OK ==
|
|
|
|
GNUNET_CRYPTO_eddsa_sign (master_priv,
|
|
|
|
&issue->purpose,
|
|
|
|
&issue->signature));
|
2015-01-08 18:37:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-03-15 22:33:28 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param signkey_filename
|
|
|
|
* @return
|
|
|
|
*/
|
2015-01-08 18:37:20 +01:00
|
|
|
static int
|
|
|
|
check_signkey_valid (const char *signkey_filename)
|
|
|
|
{
|
|
|
|
// FIXME: do real checks
|
|
|
|
return GNUNET_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-03-15 22:33:28 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @return
|
|
|
|
*/
|
2015-01-26 12:22:26 +01:00
|
|
|
static int
|
2015-01-08 18:37:20 +01:00
|
|
|
mint_keys_update_signkeys ()
|
|
|
|
{
|
|
|
|
struct GNUNET_TIME_Relative signkey_duration;
|
|
|
|
struct GNUNET_TIME_Absolute anchor;
|
|
|
|
char *signkey_dir;
|
|
|
|
|
2015-03-15 22:33:28 +01:00
|
|
|
if (GNUNET_OK !=
|
|
|
|
GNUNET_CONFIGURATION_get_value_time (kcfg,
|
|
|
|
"mint_keys",
|
|
|
|
"signkey_duration",
|
|
|
|
&signkey_duration))
|
2015-01-08 18:37:20 +01:00
|
|
|
{
|
2015-03-15 22:33:28 +01:00
|
|
|
fprintf (stderr,
|
|
|
|
"Cannot read config value mint_keys.signkey_duration\n");
|
2015-01-08 18:37:20 +01:00
|
|
|
return GNUNET_SYSERR;
|
|
|
|
}
|
2015-03-15 22:33:28 +01:00
|
|
|
ROUND_TO_SECS (signkey_duration,
|
|
|
|
rel_value_us);
|
2015-01-08 18:37:20 +01:00
|
|
|
signkey_dir = get_signkey_dir ();
|
|
|
|
// make sure the directory exists
|
2015-03-15 22:33:28 +01:00
|
|
|
if (GNUNET_OK !=
|
|
|
|
GNUNET_DISK_directory_create (signkey_dir))
|
2015-01-08 18:37:20 +01:00
|
|
|
{
|
2015-03-15 22:33:28 +01:00
|
|
|
fprintf (stderr,
|
|
|
|
"Failed to create signing key directory\n");
|
2015-01-08 18:37:20 +01:00
|
|
|
return GNUNET_SYSERR;
|
|
|
|
}
|
|
|
|
|
2015-03-15 22:33:28 +01:00
|
|
|
get_anchor (signkey_dir,
|
|
|
|
signkey_duration,
|
|
|
|
GNUNET_TIME_UNIT_ZERO,
|
|
|
|
&anchor);
|
2015-01-08 18:37:20 +01:00
|
|
|
|
2015-03-15 22:33:28 +01:00
|
|
|
while (anchor.abs_value_us < lookahead_sign_stamp.abs_value_us)
|
|
|
|
{
|
2015-01-08 18:37:20 +01:00
|
|
|
char *skf;
|
2015-03-15 22:33:28 +01:00
|
|
|
|
2015-01-08 18:37:20 +01:00
|
|
|
skf = get_signkey_file (anchor);
|
2015-03-15 22:33:28 +01:00
|
|
|
if (GNUNET_YES !=
|
|
|
|
GNUNET_DISK_file_test (skf))
|
2015-01-08 18:37:20 +01:00
|
|
|
{
|
2015-01-09 18:18:59 +01:00
|
|
|
struct TALER_MINT_SignKeyIssuePriv signkey_issue;
|
2015-01-08 18:37:20 +01:00
|
|
|
ssize_t nwrite;
|
2015-03-15 22:33:28 +01:00
|
|
|
|
|
|
|
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
|
|
|
"Generating signing key for %s.\n",
|
|
|
|
GNUNET_STRINGS_absolute_time_to_string (anchor));
|
|
|
|
create_signkey_issue_priv (anchor,
|
|
|
|
signkey_duration,
|
|
|
|
&signkey_issue);
|
|
|
|
nwrite = GNUNET_DISK_fn_write (skf,
|
|
|
|
&signkey_issue,
|
|
|
|
sizeof (struct TALER_MINT_SignKeyIssue),
|
|
|
|
GNUNET_DISK_PERM_USER_WRITE | GNUNET_DISK_PERM_USER_READ);
|
2015-01-08 18:37:20 +01:00
|
|
|
if (nwrite != sizeof (struct TALER_MINT_SignKeyIssue))
|
|
|
|
{
|
2015-03-15 22:33:28 +01:00
|
|
|
fprintf (stderr,
|
|
|
|
"Failed to write to file `%s': %s\n",
|
|
|
|
skf,
|
|
|
|
STRERROR (errno));
|
2015-01-08 18:37:20 +01:00
|
|
|
return GNUNET_SYSERR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (GNUNET_OK != check_signkey_valid (skf))
|
|
|
|
{
|
|
|
|
return GNUNET_SYSERR;
|
|
|
|
}
|
|
|
|
anchor = GNUNET_TIME_absolute_add (anchor, signkey_duration);
|
|
|
|
}
|
|
|
|
return GNUNET_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-03-15 22:33:28 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param ct
|
|
|
|
* @param params
|
|
|
|
* @return
|
|
|
|
*/
|
2015-01-26 12:22:26 +01:00
|
|
|
static int
|
2015-03-15 22:33:28 +01:00
|
|
|
get_cointype_params (const char *ct,
|
|
|
|
struct CoinTypeParams *params)
|
2015-01-08 18:37:20 +01:00
|
|
|
{
|
|
|
|
const char *dir;
|
2015-03-15 22:33:28 +01:00
|
|
|
|
|
|
|
if (GNUNET_OK !=
|
|
|
|
GNUNET_CONFIGURATION_get_value_time (kcfg,
|
|
|
|
"mint_denom_duration_withdraw",
|
|
|
|
ct,
|
|
|
|
¶ms->duration_withdraw))
|
2015-01-08 18:37:20 +01:00
|
|
|
{
|
2015-03-15 22:33:28 +01:00
|
|
|
fprintf (stderr,
|
|
|
|
"Withdraw duration not given for coin type '%s'\n",
|
|
|
|
ct);
|
2015-01-08 18:37:20 +01:00
|
|
|
return GNUNET_SYSERR;
|
|
|
|
}
|
2015-03-15 22:33:28 +01:00
|
|
|
ROUND_TO_SECS (params->duration_withdraw,
|
|
|
|
rel_value_us);
|
|
|
|
if (GNUNET_OK !=
|
|
|
|
GNUNET_CONFIGURATION_get_value_time (kcfg,
|
|
|
|
"mint_denom_duration_spend",
|
|
|
|
ct,
|
|
|
|
¶ms->duration_spend))
|
2015-01-08 18:37:20 +01:00
|
|
|
{
|
2015-03-15 22:33:28 +01:00
|
|
|
fprintf (stderr,
|
|
|
|
"Spend duration not given for coin type '%s'\n",
|
|
|
|
ct);
|
2015-01-08 18:37:20 +01:00
|
|
|
return GNUNET_SYSERR;
|
|
|
|
}
|
|
|
|
ROUND_TO_SECS (params->duration_spend, rel_value_us);
|
2015-03-15 22:33:28 +01:00
|
|
|
if (GNUNET_OK !=
|
|
|
|
GNUNET_CONFIGURATION_get_value_time (kcfg,
|
|
|
|
"mint_denom_duration_overlap",
|
|
|
|
ct,
|
|
|
|
¶ms->duration_overlap))
|
2015-01-08 18:37:20 +01:00
|
|
|
{
|
2015-03-15 22:33:28 +01:00
|
|
|
fprintf (stderr,
|
|
|
|
"Overlap duration not given for coin type '%s'\n",
|
|
|
|
ct);
|
2015-01-08 18:37:20 +01:00
|
|
|
return GNUNET_SYSERR;
|
|
|
|
}
|
2015-03-15 22:33:28 +01:00
|
|
|
ROUND_TO_SECS (params->duration_overlap,
|
|
|
|
rel_value_us);
|
2015-01-08 18:37:20 +01:00
|
|
|
|
2015-03-15 22:33:28 +01:00
|
|
|
if (GNUNET_OK !=
|
|
|
|
config_get_denom ("mint_denom_value",
|
|
|
|
ct,
|
|
|
|
¶ms->value))
|
2015-01-08 18:37:20 +01:00
|
|
|
{
|
2015-03-15 22:33:28 +01:00
|
|
|
fprintf (stderr,
|
|
|
|
"Value not given for coin type '%s'\n",
|
|
|
|
ct);
|
2015-01-08 18:37:20 +01:00
|
|
|
return GNUNET_SYSERR;
|
|
|
|
}
|
|
|
|
|
2015-03-15 22:33:28 +01:00
|
|
|
if (GNUNET_OK !=
|
|
|
|
config_get_denom ("mint_denom_fee_withdraw",
|
|
|
|
ct,
|
|
|
|
¶ms->fee_withdraw))
|
2015-01-08 18:37:20 +01:00
|
|
|
{
|
2015-03-15 22:33:28 +01:00
|
|
|
fprintf (stderr,
|
|
|
|
"Withdraw fee not given for coin type '%s'\n",
|
|
|
|
ct);
|
2015-01-08 18:37:20 +01:00
|
|
|
return GNUNET_SYSERR;
|
|
|
|
}
|
|
|
|
|
2015-03-15 22:33:28 +01:00
|
|
|
if (GNUNET_OK !=
|
|
|
|
config_get_denom ("mint_denom_fee_deposit",
|
|
|
|
ct,
|
|
|
|
¶ms->fee_deposit))
|
2015-01-08 18:37:20 +01:00
|
|
|
{
|
2015-03-15 22:33:28 +01:00
|
|
|
fprintf (stderr,
|
|
|
|
"Deposit fee not given for coin type '%s'\n",
|
|
|
|
ct);
|
2015-01-08 18:37:20 +01:00
|
|
|
return GNUNET_SYSERR;
|
|
|
|
}
|
|
|
|
|
2015-03-15 22:33:28 +01:00
|
|
|
if (GNUNET_OK !=
|
|
|
|
config_get_denom ("mint_denom_fee_refresh",
|
|
|
|
ct,
|
|
|
|
¶ms->fee_refresh))
|
2015-01-08 18:37:20 +01:00
|
|
|
{
|
2015-03-15 22:33:28 +01:00
|
|
|
fprintf (stderr,
|
|
|
|
"Deposit fee not given for coin type '%s'\n",
|
|
|
|
ct);
|
2015-01-08 18:37:20 +01:00
|
|
|
return GNUNET_SYSERR;
|
|
|
|
}
|
|
|
|
|
|
|
|
dir = get_cointype_dir (params);
|
|
|
|
get_anchor (dir, params->duration_spend, params->duration_overlap, ¶ms->anchor);
|
|
|
|
return GNUNET_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-03-15 22:33:28 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param params
|
|
|
|
* @param dki
|
|
|
|
*/
|
2015-01-08 18:37:20 +01:00
|
|
|
static void
|
2015-01-09 18:18:59 +01:00
|
|
|
create_denomkey_issue (struct CoinTypeParams *params,
|
|
|
|
struct TALER_MINT_DenomKeyIssuePriv *dki)
|
2015-01-08 18:37:20 +01:00
|
|
|
{
|
2015-01-27 14:55:05 +01:00
|
|
|
GNUNET_assert (NULL != (dki->denom_priv = GNUNET_CRYPTO_rsa_private_key_create (RSA_KEYSIZE)));
|
2015-03-15 18:27:32 +01:00
|
|
|
dki->denom_pub = GNUNET_CRYPTO_rsa_private_key_get_public (dki->denom_priv);
|
|
|
|
GNUNET_CRYPTO_rsa_public_key_hash (dki->denom_pub,
|
|
|
|
&dki->issue.denom_hash);
|
2015-01-09 18:18:59 +01:00
|
|
|
dki->issue.master = *master_pub;
|
|
|
|
dki->issue.start = GNUNET_TIME_absolute_hton (params->anchor);
|
|
|
|
dki->issue.expire_withdraw =
|
|
|
|
GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_add (params->anchor,
|
2015-01-08 18:37:20 +01:00
|
|
|
params->duration_withdraw));
|
2015-01-09 18:18:59 +01:00
|
|
|
dki->issue.expire_spend =
|
|
|
|
GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_add (params->anchor,
|
2015-01-08 18:37:20 +01:00
|
|
|
params->duration_spend));
|
2015-01-09 18:18:59 +01:00
|
|
|
dki->issue.value = TALER_amount_hton (params->value);
|
|
|
|
dki->issue.fee_withdraw = TALER_amount_hton (params->fee_withdraw);
|
|
|
|
dki->issue.fee_deposit = TALER_amount_hton (params->fee_deposit);
|
|
|
|
dki->issue.fee_refresh = TALER_amount_hton (params->fee_refresh);
|
|
|
|
|
|
|
|
dki->issue.purpose.purpose = htonl (TALER_SIGNATURE_MASTER_DENOM);
|
2015-03-15 22:33:28 +01:00
|
|
|
dki->issue.purpose.size = htonl (sizeof (struct TALER_MINT_DenomKeyIssuePriv) -
|
|
|
|
offsetof (struct TALER_MINT_DenomKeyIssuePriv,
|
|
|
|
issue.purpose));
|
2015-01-09 18:18:59 +01:00
|
|
|
|
2015-03-09 11:24:35 +01:00
|
|
|
GNUNET_assert (GNUNET_OK ==
|
|
|
|
GNUNET_CRYPTO_eddsa_sign (master_priv,
|
|
|
|
&dki->issue.purpose,
|
|
|
|
&dki->issue.signature));
|
2015-01-08 18:37:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-03-15 22:33:28 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param filename
|
|
|
|
* @param params
|
|
|
|
* @return
|
|
|
|
*/
|
2015-01-08 18:37:20 +01:00
|
|
|
static int
|
2015-03-15 22:33:28 +01:00
|
|
|
check_cointype_valid (const char *filename,
|
|
|
|
struct CoinTypeParams *params)
|
2015-01-08 18:37:20 +01:00
|
|
|
{
|
|
|
|
// FIXME: add real checks
|
|
|
|
return GNUNET_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-03-15 22:33:28 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param coin_alias
|
|
|
|
* @return
|
|
|
|
*/
|
2015-01-26 12:22:26 +01:00
|
|
|
static int
|
2015-01-08 18:37:20 +01:00
|
|
|
mint_keys_update_cointype (const char *coin_alias)
|
|
|
|
{
|
|
|
|
struct CoinTypeParams p;
|
|
|
|
const char *cointype_dir;
|
|
|
|
|
|
|
|
if (GNUNET_OK != get_cointype_params (coin_alias, &p))
|
|
|
|
return GNUNET_SYSERR;
|
|
|
|
|
|
|
|
cointype_dir = get_cointype_dir (&p);
|
|
|
|
if (GNUNET_OK != GNUNET_DISK_directory_create (cointype_dir))
|
|
|
|
return GNUNET_SYSERR;
|
|
|
|
|
2015-03-15 22:33:28 +01:00
|
|
|
while (p.anchor.abs_value_us < lookahead_sign_stamp.abs_value_us)
|
|
|
|
{
|
2015-01-08 18:37:20 +01:00
|
|
|
const char *dkf;
|
2015-03-15 22:33:28 +01:00
|
|
|
|
2015-01-08 18:37:20 +01:00
|
|
|
dkf = get_cointype_file (&p, p.anchor);
|
|
|
|
|
|
|
|
if (GNUNET_YES != GNUNET_DISK_file_test (dkf))
|
|
|
|
{
|
2015-01-09 18:18:59 +01:00
|
|
|
struct TALER_MINT_DenomKeyIssuePriv denomkey_issue;
|
2015-01-08 18:37:20 +01:00
|
|
|
int ret;
|
2015-03-15 22:33:28 +01:00
|
|
|
|
|
|
|
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
|
|
|
"Generating denomination key for type '%s', start %s at %s\n",
|
|
|
|
coin_alias,
|
|
|
|
GNUNET_STRINGS_absolute_time_to_string (p.anchor),
|
|
|
|
dkf);
|
|
|
|
create_denomkey_issue (&p,
|
|
|
|
&denomkey_issue);
|
|
|
|
ret = TALER_MINT_write_denom_key (dkf,
|
|
|
|
&denomkey_issue);
|
2015-01-26 12:22:26 +01:00
|
|
|
GNUNET_CRYPTO_rsa_private_key_free (denomkey_issue.denom_priv);
|
2015-01-08 18:37:20 +01:00
|
|
|
if (GNUNET_OK != ret)
|
|
|
|
{
|
2015-03-15 22:33:28 +01:00
|
|
|
fprintf (stderr,
|
|
|
|
"Failed to write to file `%s'\n",
|
|
|
|
dkf);
|
2015-01-08 18:37:20 +01:00
|
|
|
return GNUNET_SYSERR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (GNUNET_OK != check_cointype_valid (dkf, &p))
|
|
|
|
{
|
|
|
|
return GNUNET_SYSERR;
|
|
|
|
}
|
|
|
|
p.anchor = GNUNET_TIME_absolute_add (p.anchor, p.duration_spend);
|
|
|
|
p.anchor = GNUNET_TIME_absolute_subtract (p.anchor, p.duration_overlap);
|
|
|
|
}
|
|
|
|
return GNUNET_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-03-15 22:33:28 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @return
|
|
|
|
*/
|
2015-01-26 12:22:26 +01:00
|
|
|
static int
|
2015-01-08 18:37:20 +01:00
|
|
|
mint_keys_update_denomkeys ()
|
|
|
|
{
|
|
|
|
char *coin_types;
|
|
|
|
char *ct;
|
|
|
|
char *tok_ctx;
|
|
|
|
|
2015-03-15 22:33:28 +01:00
|
|
|
if (GNUNET_OK !=
|
|
|
|
GNUNET_CONFIGURATION_get_value_string (kcfg,
|
|
|
|
"mint_keys",
|
|
|
|
"coin_types",
|
|
|
|
&coin_types))
|
2015-01-08 18:37:20 +01:00
|
|
|
{
|
2015-03-15 22:33:28 +01:00
|
|
|
fprintf (stderr,
|
|
|
|
"mint_keys.coin_types not in configuration\n");
|
2015-01-08 18:37:20 +01:00
|
|
|
return GNUNET_SYSERR;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (ct = strtok_r (coin_types, " ", &tok_ctx);
|
|
|
|
ct != NULL;
|
|
|
|
ct = strtok_r (NULL, " ", &tok_ctx))
|
|
|
|
{
|
|
|
|
if (GNUNET_OK != mint_keys_update_cointype (ct))
|
|
|
|
{
|
|
|
|
GNUNET_free (coin_types);
|
|
|
|
return GNUNET_SYSERR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
GNUNET_free (coin_types);
|
|
|
|
return GNUNET_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-03-15 22:33:28 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @return
|
|
|
|
*/
|
2015-01-08 18:37:20 +01:00
|
|
|
static int
|
|
|
|
mint_keys_update ()
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
struct GNUNET_TIME_Relative lookahead_sign;
|
2015-03-15 22:33:28 +01:00
|
|
|
|
|
|
|
if (GNUNET_OK !=
|
|
|
|
GNUNET_CONFIGURATION_get_value_time (kcfg,
|
|
|
|
"mint_keys",
|
|
|
|
"lookahead_sign",
|
|
|
|
&lookahead_sign))
|
2015-01-08 18:37:20 +01:00
|
|
|
{
|
2015-03-15 22:33:28 +01:00
|
|
|
fprintf (stderr,
|
|
|
|
"mint_keys.lookahead_sign not found\n");
|
2015-01-08 18:37:20 +01:00
|
|
|
return GNUNET_SYSERR;
|
|
|
|
}
|
2015-03-15 22:33:28 +01:00
|
|
|
if (0 == lookahead_sign.rel_value_us)
|
2015-01-08 18:37:20 +01:00
|
|
|
{
|
2015-03-15 22:33:28 +01:00
|
|
|
fprintf (stderr,
|
|
|
|
"mint_keys.lookahead_sign must not be zero\n");
|
2015-01-08 18:37:20 +01:00
|
|
|
return GNUNET_SYSERR;
|
|
|
|
}
|
2015-03-15 22:33:28 +01:00
|
|
|
ROUND_TO_SECS (lookahead_sign,
|
|
|
|
rel_value_us);
|
|
|
|
lookahead_sign_stamp = GNUNET_TIME_absolute_add (now,
|
|
|
|
lookahead_sign);
|
2015-01-08 18:37:20 +01:00
|
|
|
|
|
|
|
ret = mint_keys_update_signkeys ();
|
|
|
|
if (GNUNET_OK != ret)
|
|
|
|
return GNUNET_SYSERR;
|
|
|
|
|
|
|
|
return mint_keys_update_denomkeys ();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The main function of the keyup tool
|
|
|
|
*
|
|
|
|
* @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)
|
|
|
|
{
|
|
|
|
static const struct GNUNET_GETOPT_CommandLineOption options[] = {
|
|
|
|
GNUNET_GETOPT_OPTION_HELP ("gnunet-mint-keyup OPTIONS"),
|
|
|
|
{'m', "master-key", "FILE",
|
|
|
|
"master key file (private key)", 1,
|
|
|
|
&GNUNET_GETOPT_set_filename, &masterkeyfile},
|
|
|
|
{'d', "mint-dir", "DIR",
|
|
|
|
"mint directory with keys to update", 1,
|
|
|
|
&GNUNET_GETOPT_set_filename, &mintdir},
|
|
|
|
{'t', "time", "TIMESTAMP",
|
|
|
|
"pretend it is a different time for the update", 0,
|
|
|
|
&GNUNET_GETOPT_set_string, &pretend_time_str},
|
|
|
|
GNUNET_GETOPT_OPTION_END
|
|
|
|
};
|
|
|
|
|
2015-03-15 22:33:28 +01:00
|
|
|
GNUNET_assert (GNUNET_OK ==
|
|
|
|
GNUNET_log_setup ("taler-mint-keyup",
|
|
|
|
"WARNING",
|
|
|
|
NULL));
|
2015-01-08 18:37:20 +01:00
|
|
|
|
2015-03-15 22:33:28 +01:00
|
|
|
if (GNUNET_GETOPT_run ("taler-mint-keyup",
|
|
|
|
options,
|
|
|
|
argc, argv) < 0)
|
2015-01-08 18:37:20 +01:00
|
|
|
return 1;
|
|
|
|
if (NULL == mintdir)
|
|
|
|
{
|
2015-03-15 22:33:28 +01:00
|
|
|
fprintf (stderr,
|
|
|
|
"mint directory not given\n");
|
2015-01-08 18:37:20 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NULL != pretend_time_str)
|
|
|
|
{
|
2015-03-15 22:33:28 +01:00
|
|
|
if (GNUNET_OK !=
|
|
|
|
GNUNET_STRINGS_fancy_time_to_absolute (pretend_time_str,
|
|
|
|
&now))
|
2015-01-08 18:37:20 +01:00
|
|
|
{
|
2015-03-15 22:33:28 +01:00
|
|
|
fprintf (stderr,
|
|
|
|
"timestamp invalid\n");
|
2015-01-08 18:37:20 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
now = GNUNET_TIME_absolute_get ();
|
|
|
|
}
|
|
|
|
ROUND_TO_SECS (now, abs_value_us);
|
|
|
|
|
2015-01-28 14:55:25 +01:00
|
|
|
kcfg = TALER_config_load (mintdir);
|
2015-01-08 18:37:20 +01:00
|
|
|
if (NULL == kcfg)
|
|
|
|
{
|
2015-03-15 22:33:28 +01:00
|
|
|
fprintf (stderr,
|
|
|
|
"Failed to load mint configuration\n");
|
2015-01-08 18:37:20 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NULL == masterkeyfile)
|
|
|
|
{
|
2015-03-15 22:33:28 +01:00
|
|
|
fprintf (stderr,
|
|
|
|
"master key file not given\n");
|
2015-01-08 18:37:20 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
master_priv = GNUNET_CRYPTO_eddsa_key_create_from_file (masterkeyfile);
|
|
|
|
if (NULL == master_priv)
|
|
|
|
{
|
2015-03-15 22:33:28 +01:00
|
|
|
fprintf (stderr,
|
|
|
|
"Failed to initialize master key from file `%s'\n",
|
|
|
|
masterkeyfile);
|
2015-01-08 18:37:20 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
master_pub = GNUNET_new (struct GNUNET_CRYPTO_EddsaPublicKey);
|
2015-03-15 22:33:28 +01:00
|
|
|
GNUNET_CRYPTO_eddsa_key_get_public (master_priv,
|
|
|
|
master_pub);
|
2015-01-08 18:37:20 +01:00
|
|
|
|
|
|
|
// check if key from file matches the one from the configuration
|
|
|
|
{
|
|
|
|
struct GNUNET_CRYPTO_EddsaPublicKey master_pub_from_cfg;
|
2015-03-15 22:33:28 +01:00
|
|
|
|
2015-01-27 18:35:17 +01:00
|
|
|
if (GNUNET_OK !=
|
2015-03-15 22:33:28 +01:00
|
|
|
GNUNET_CONFIGURATION_get_data (kcfg,
|
|
|
|
"mint",
|
|
|
|
"master_pub",
|
2015-01-27 18:35:17 +01:00
|
|
|
&master_pub_from_cfg,
|
|
|
|
sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)))
|
2015-01-08 18:37:20 +01:00
|
|
|
{
|
2015-03-15 22:33:28 +01:00
|
|
|
fprintf (stderr,
|
|
|
|
"Master public key missing in configuration (mint.master_pub)\n");
|
2015-01-08 18:37:20 +01:00
|
|
|
return 1;
|
|
|
|
}
|
2015-03-15 22:33:28 +01:00
|
|
|
if (0 !=
|
|
|
|
memcmp (master_pub,
|
|
|
|
&master_pub_from_cfg,
|
|
|
|
sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)))
|
2015-01-08 18:37:20 +01:00
|
|
|
{
|
2015-03-15 22:33:28 +01:00
|
|
|
fprintf (stderr,
|
|
|
|
"Mismatch between key from mint configuration and master private key file from command line.\n");
|
2015-01-08 18:37:20 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (GNUNET_OK != mint_keys_update ())
|
|
|
|
return 1;
|
|
|
|
return 0;
|
|
|
|
}
|
2015-03-15 22:33:28 +01:00
|
|
|
|
|
|
|
/* end of taler-mint-keyup.c */
|