implement denomination key revocation logic in exchangedb and taler-exchange-keyup (part of #3887)
This commit is contained in:
parent
ef6d9cc56d
commit
209076ebd3
@ -1,4 +1,4 @@
|
|||||||
.TH TALER\-EXCHANGE\-KEYUP 1 "Apr 22, 2015" "GNU Taler"
|
.TH TALER\-EXCHANGE\-KEYUP 1 "Apr 7, 2017" "GNU Taler"
|
||||||
|
|
||||||
.SH NAME
|
.SH NAME
|
||||||
taler\-exchange\-keyup \- Setup Taler exchange denomination and signing keys.
|
taler\-exchange\-keyup \- Setup Taler exchange denomination and signing keys.
|
||||||
@ -25,6 +25,9 @@ Location of the private EdDSA offline master key of the exchange.
|
|||||||
.IP "\-o FILE, \-\-ouptut=FILE"
|
.IP "\-o FILE, \-\-ouptut=FILE"
|
||||||
Where to write a denomination key signing request file to be given to the auditor.
|
Where to write a denomination key signing request file to be given to the auditor.
|
||||||
.B
|
.B
|
||||||
|
.IP "\-r DKH, \-\-revoke=DKH"
|
||||||
|
Revoke the denomination key where the denomination public key's hash is DKH.
|
||||||
|
.B
|
||||||
.IP "\-t TIMESTAMP, \-\-time=TIMESTAMP"
|
.IP "\-t TIMESTAMP, \-\-time=TIMESTAMP"
|
||||||
Operate as if the current time was TIMESTAMP.
|
Operate as if the current time was TIMESTAMP.
|
||||||
.B
|
.B
|
||||||
|
@ -122,6 +122,7 @@ exchange_signkeys_check ()
|
|||||||
* @param cls closure (NULL)
|
* @param cls closure (NULL)
|
||||||
* @param dki the denomination key
|
* @param dki the denomination key
|
||||||
* @param alias coin alias
|
* @param alias coin alias
|
||||||
|
* @param was_revoked #GNUNET_YES if the @a dki was revoked and wallets should trigger /payback
|
||||||
* @return #GNUNET_OK to continue to iterate,
|
* @return #GNUNET_OK to continue to iterate,
|
||||||
* #GNUNET_NO to stop iteration with no error,
|
* #GNUNET_NO to stop iteration with no error,
|
||||||
* #GNUNET_SYSERR to abort iteration with error!
|
* #GNUNET_SYSERR to abort iteration with error!
|
||||||
@ -129,7 +130,8 @@ exchange_signkeys_check ()
|
|||||||
static int
|
static int
|
||||||
denomkeys_iter (void *cls,
|
denomkeys_iter (void *cls,
|
||||||
const char *alias,
|
const char *alias,
|
||||||
const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki)
|
const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki,
|
||||||
|
int was_revoked)
|
||||||
{
|
{
|
||||||
struct GNUNET_HashCode hc;
|
struct GNUNET_HashCode hc;
|
||||||
|
|
||||||
@ -190,7 +192,23 @@ denomkeys_iter (void *cls,
|
|||||||
static int
|
static int
|
||||||
exchange_denomkeys_check ()
|
exchange_denomkeys_check ()
|
||||||
{
|
{
|
||||||
|
struct TALER_MasterPublicKeyP master_public_key_from_cfg;
|
||||||
|
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_CONFIGURATION_get_data (kcfg,
|
||||||
|
"exchange",
|
||||||
|
"master_public_key",
|
||||||
|
&master_public_key_from_cfg,
|
||||||
|
sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)))
|
||||||
|
{
|
||||||
|
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
|
||||||
|
"exchange",
|
||||||
|
"master_public_key");
|
||||||
|
global_ret = 1;
|
||||||
|
return GNUNET_NO;
|
||||||
|
}
|
||||||
if (0 > TALER_EXCHANGEDB_denomination_keys_iterate (exchange_directory,
|
if (0 > TALER_EXCHANGEDB_denomination_keys_iterate (exchange_directory,
|
||||||
|
&master_public_key_from_cfg,
|
||||||
&denomkeys_iter,
|
&denomkeys_iter,
|
||||||
NULL))
|
NULL))
|
||||||
return GNUNET_NO;
|
return GNUNET_NO;
|
||||||
|
@ -220,6 +220,11 @@ static struct GNUNET_TIME_Absolute lookahead_sign_stamp;
|
|||||||
*/
|
*/
|
||||||
static struct GNUNET_TIME_Relative max_duration_spend;
|
static struct GNUNET_TIME_Relative max_duration_spend;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Revoke denomination key identified by this hash (if non-zero).
|
||||||
|
*/
|
||||||
|
static struct GNUNET_HashCode revoke_dkh;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return value from main().
|
* Return value from main().
|
||||||
*/
|
*/
|
||||||
@ -1018,6 +1023,106 @@ create_wire_fees ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closure for functions processing a request to revoke a denomination
|
||||||
|
* public key and request the wallets to initiate /payback.
|
||||||
|
*/
|
||||||
|
struct RevokeClosure
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Hash of the denomination public key to revoke.
|
||||||
|
*/
|
||||||
|
const struct GNUNET_HashCode *hc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base directory for keys.
|
||||||
|
*/
|
||||||
|
char *basedir;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set to #GNUNET_OK if we found a matching key,
|
||||||
|
* Set to #GNUNET_SYSERR on error.
|
||||||
|
*/
|
||||||
|
int ok;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Revoke denomination keys matching the given hash.
|
||||||
|
*
|
||||||
|
* @param cls a `struct RevokeClosure` with information about what to revoke
|
||||||
|
* @param dki the denomination key
|
||||||
|
* @param alias coin alias
|
||||||
|
* @param was_revoked #GNUNET_YES if the @a dki was revoked and wallets should trigger /payback
|
||||||
|
* @return #GNUNET_OK to continue to iterate,
|
||||||
|
* #GNUNET_NO to stop iteration with no error,
|
||||||
|
* #GNUNET_SYSERR to abort iteration with error!
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
exchange_keys_revoke_by_dki (void *cls,
|
||||||
|
const char *alias,
|
||||||
|
const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki,
|
||||||
|
int was_revoked)
|
||||||
|
{
|
||||||
|
struct RevokeClosure *rc = cls;
|
||||||
|
|
||||||
|
if (GNUNET_YES == was_revoked)
|
||||||
|
return GNUNET_OK; /* refuse to do it twice */
|
||||||
|
if (0 != memcmp (rc->hc,
|
||||||
|
&dki->issue.properties.denom_hash,
|
||||||
|
sizeof (struct GNUNET_HashCode)))
|
||||||
|
return GNUNET_OK;
|
||||||
|
rc->ok = GNUNET_OK;
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
TALER_EXCHANGEDB_denomination_key_revoke (rc->basedir,
|
||||||
|
alias,
|
||||||
|
dki,
|
||||||
|
&master_priv))
|
||||||
|
{
|
||||||
|
rc->ok = GNUNET_SYSERR;
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
return GNUNET_NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Revoke the denomination key matching @a hc and request /payback to be
|
||||||
|
* initiated.
|
||||||
|
*
|
||||||
|
* @param hc denomination key hash to revoke
|
||||||
|
* @return #GNUNET_OK on success,
|
||||||
|
* #GNUNET_NO if @a hc was not found
|
||||||
|
* #GNUNET_SYSERR on error
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
revoke_denomination (const struct GNUNET_HashCode *hc)
|
||||||
|
{
|
||||||
|
struct RevokeClosure rc;
|
||||||
|
|
||||||
|
rc.hc = hc;
|
||||||
|
rc.ok = GNUNET_NO;
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_CONFIGURATION_get_value_filename (kcfg,
|
||||||
|
"exchange",
|
||||||
|
"KEYDIR",
|
||||||
|
&rc.basedir))
|
||||||
|
{
|
||||||
|
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
|
||||||
|
"exchange",
|
||||||
|
"KEYDIR");
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
TALER_EXCHANGEDB_denomination_keys_iterate (rc.basedir,
|
||||||
|
&master_public_key,
|
||||||
|
&exchange_keys_revoke_by_dki,
|
||||||
|
&rc);
|
||||||
|
GNUNET_free (rc.basedir);
|
||||||
|
return rc.ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main function that will be run.
|
* Main function that will be run.
|
||||||
*
|
*
|
||||||
@ -1032,6 +1137,7 @@ run (void *cls,
|
|||||||
const char *cfgfile,
|
const char *cfgfile,
|
||||||
const struct GNUNET_CONFIGURATION_Handle *cfg)
|
const struct GNUNET_CONFIGURATION_Handle *cfg)
|
||||||
{
|
{
|
||||||
|
static struct GNUNET_HashCode zero;
|
||||||
struct GNUNET_TIME_Relative lookahead_sign;
|
struct GNUNET_TIME_Relative lookahead_sign;
|
||||||
struct GNUNET_CRYPTO_EddsaPrivateKey *eddsa_priv;
|
struct GNUNET_CRYPTO_EddsaPrivateKey *eddsa_priv;
|
||||||
|
|
||||||
@ -1119,7 +1225,7 @@ run (void *cls,
|
|||||||
|
|
||||||
/* check if key from file matches the one from the configuration */
|
/* check if key from file matches the one from the configuration */
|
||||||
{
|
{
|
||||||
struct GNUNET_CRYPTO_EddsaPublicKey master_public_key_from_cfg;
|
struct TALER_MasterPublicKeyP master_public_key_from_cfg;
|
||||||
|
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
GNUNET_CONFIGURATION_get_data (kcfg,
|
GNUNET_CONFIGURATION_get_data (kcfg,
|
||||||
@ -1137,7 +1243,7 @@ run (void *cls,
|
|||||||
if (0 !=
|
if (0 !=
|
||||||
memcmp (&master_public_key,
|
memcmp (&master_public_key,
|
||||||
&master_public_key_from_cfg,
|
&master_public_key_from_cfg,
|
||||||
sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)))
|
sizeof (struct TALER_MasterPublicKeyP)))
|
||||||
{
|
{
|
||||||
GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
|
GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
|
||||||
"exchange",
|
"exchange",
|
||||||
@ -1190,6 +1296,15 @@ run (void *cls,
|
|||||||
global_ret = 1;
|
global_ret = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if ( (0 != memcmp (&zero,
|
||||||
|
&revoke_dkh,
|
||||||
|
sizeof (zero))) &&
|
||||||
|
(GNUNET_OK !=
|
||||||
|
revoke_denomination (&revoke_dkh)) )
|
||||||
|
{
|
||||||
|
global_ret = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1226,11 +1341,16 @@ main (int argc,
|
|||||||
"FILENAME",
|
"FILENAME",
|
||||||
"auditor denomination key signing request file to create",
|
"auditor denomination key signing request file to create",
|
||||||
&auditorrequestfile),
|
&auditorrequestfile),
|
||||||
|
GNUNET_GETOPT_option_base32_auto ('r',
|
||||||
|
"revoke",
|
||||||
|
"DKH",
|
||||||
|
"revoke denomination key hash (DKH) and request wallets to initiate /payback",
|
||||||
|
&revoke_dkh),
|
||||||
GNUNET_GETOPT_option_absolute_time ('t',
|
GNUNET_GETOPT_option_absolute_time ('t',
|
||||||
"time",
|
"time",
|
||||||
"TIMESTAMP",
|
"TIMESTAMP",
|
||||||
"pretend it is a different time for the update",
|
"pretend it is a different time for the update",
|
||||||
&now),
|
&now),
|
||||||
GNUNET_GETOPT_OPTION_END
|
GNUNET_GETOPT_OPTION_END
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -188,10 +188,10 @@ main (int argc, char *const *argv)
|
|||||||
GNUNET_GETOPT_option_help ("Deposit funds into a Taler reserve"),
|
GNUNET_GETOPT_option_help ("Deposit funds into a Taler reserve"),
|
||||||
GNUNET_GETOPT_option_mandatory
|
GNUNET_GETOPT_option_mandatory
|
||||||
(GNUNET_GETOPT_option_base32_auto ('R',
|
(GNUNET_GETOPT_option_base32_auto ('R',
|
||||||
"reserve",
|
"reserve",
|
||||||
"KEY",
|
"KEY",
|
||||||
"reserve (public key) to modify",
|
"reserve (public key) to modify",
|
||||||
&reserve_pub)),
|
&reserve_pub)),
|
||||||
GNUNET_GETOPT_OPTION_END
|
GNUNET_GETOPT_OPTION_END
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -210,6 +210,7 @@ TALER_EXCHANGE_conf_duration_provide ()
|
|||||||
* @param cls closure
|
* @param cls closure
|
||||||
* @param dki the denomination key issue
|
* @param dki the denomination key issue
|
||||||
* @param alias coin alias
|
* @param alias coin alias
|
||||||
|
* @param was_revoked #GNUNET_YES if @a dki has been revoked
|
||||||
* @return #GNUNET_OK to continue to iterate,
|
* @return #GNUNET_OK to continue to iterate,
|
||||||
* #GNUNET_NO to stop iteration with no error,
|
* #GNUNET_NO to stop iteration with no error,
|
||||||
* #GNUNET_SYSERR to abort iteration with error!
|
* #GNUNET_SYSERR to abort iteration with error!
|
||||||
@ -217,7 +218,8 @@ TALER_EXCHANGE_conf_duration_provide ()
|
|||||||
static int
|
static int
|
||||||
reload_keys_denom_iter (void *cls,
|
reload_keys_denom_iter (void *cls,
|
||||||
const char *alias,
|
const char *alias,
|
||||||
const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki)
|
const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki,
|
||||||
|
int was_revoked)
|
||||||
{
|
{
|
||||||
struct TEH_KS_StateHandle *ctx = cls;
|
struct TEH_KS_StateHandle *ctx = cls;
|
||||||
struct GNUNET_TIME_Absolute now;
|
struct GNUNET_TIME_Absolute now;
|
||||||
@ -674,6 +676,7 @@ TEH_KS_acquire_ (const char *location)
|
|||||||
"Loading keys from `%s'\n",
|
"Loading keys from `%s'\n",
|
||||||
TEH_exchange_directory);
|
TEH_exchange_directory);
|
||||||
if (-1 == TALER_EXCHANGEDB_denomination_keys_iterate (TEH_exchange_directory,
|
if (-1 == TALER_EXCHANGEDB_denomination_keys_iterate (TEH_exchange_directory,
|
||||||
|
&TEH_master_public_key,
|
||||||
&reload_keys_denom_iter,
|
&reload_keys_denom_iter,
|
||||||
key_state))
|
key_state))
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
This file is part of TALER
|
This file is part of TALER
|
||||||
Copyright (C) 2014, 2015, 2016 Inria & GNUnet e.V.
|
Copyright (C) 2014-2017 Inria & GNUnet e.V.
|
||||||
|
|
||||||
TALER is free software; you can redistribute it and/or modify it under the
|
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
|
terms of the GNU General Public License as published by the Free Software
|
||||||
@ -25,6 +25,68 @@
|
|||||||
#include "taler_exchangedb_lib.h"
|
#include "taler_exchangedb_lib.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark the given denomination key as revoked and request the wallets
|
||||||
|
* to initiate /payback.
|
||||||
|
*
|
||||||
|
* @param exchange_base_dir base directory for the exchange,
|
||||||
|
* the signing keys must be in the #TALER_EXCHANGEDB_DIR_DENOMINATION_KEYS
|
||||||
|
* subdirectory
|
||||||
|
* @param alias coin alias
|
||||||
|
* @param dki the denomination key to revoke
|
||||||
|
* @param mpriv master private key to sign
|
||||||
|
* @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
TALER_EXCHANGEDB_denomination_key_revoke (const char *exchange_base_dir,
|
||||||
|
const char *alias,
|
||||||
|
const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki,
|
||||||
|
const struct TALER_MasterPrivateKeyP *mpriv)
|
||||||
|
{
|
||||||
|
struct GNUNET_TIME_Absolute start;
|
||||||
|
struct TALER_MasterDenominationKeyRevocation rm;
|
||||||
|
struct TALER_MasterSignatureP msig;
|
||||||
|
char *fn;
|
||||||
|
struct GNUNET_DISK_FileHandle *fh;
|
||||||
|
ssize_t wrote;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = GNUNET_SYSERR;
|
||||||
|
start = GNUNET_TIME_absolute_ntoh (dki->issue.properties.start);
|
||||||
|
GNUNET_asprintf (&fn,
|
||||||
|
"%s" DIR_SEPARATOR_STR "%s" DIR_SEPARATOR_STR "%llu.rev",
|
||||||
|
exchange_base_dir,
|
||||||
|
alias,
|
||||||
|
(unsigned long long) start.abs_value_us);
|
||||||
|
|
||||||
|
rm.purpose.purpose = htonl (TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED);
|
||||||
|
rm.purpose.size = htonl (sizeof (rm));
|
||||||
|
rm.h_denom_pub = dki->issue.properties.denom_hash;
|
||||||
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
GNUNET_CRYPTO_eddsa_sign (&mpriv->eddsa_priv,
|
||||||
|
&rm.purpose,
|
||||||
|
&msig.eddsa_signature));
|
||||||
|
if (NULL == (fh = GNUNET_DISK_file_open
|
||||||
|
(fn,
|
||||||
|
GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_TRUNCATE,
|
||||||
|
GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE)))
|
||||||
|
goto cleanup;
|
||||||
|
if (GNUNET_SYSERR ==
|
||||||
|
(wrote = GNUNET_DISK_file_write (fh,
|
||||||
|
&msig,
|
||||||
|
sizeof (msig))))
|
||||||
|
goto cleanup;
|
||||||
|
if (wrote != sizeof (msig))
|
||||||
|
goto cleanup;
|
||||||
|
ret = GNUNET_OK;
|
||||||
|
cleanup:
|
||||||
|
if (NULL != fh)
|
||||||
|
(void) GNUNET_DISK_file_close (fh);
|
||||||
|
GNUNET_free (fn);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Import a denomination key from the given file.
|
* Import a denomination key from the given file.
|
||||||
*
|
*
|
||||||
@ -157,6 +219,11 @@ struct DenomkeysIterateContext
|
|||||||
*/
|
*/
|
||||||
const char *alias;
|
const char *alias;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Master public key to use to validate revocations.
|
||||||
|
*/
|
||||||
|
const struct TALER_MasterPublicKeyP *master_pub;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to call on each denomination key.
|
* Function to call on each denomination key.
|
||||||
*/
|
*/
|
||||||
@ -187,6 +254,15 @@ denomkeys_iterate_keydir_iter (void *cls,
|
|||||||
struct DenomkeysIterateContext *dic = cls;
|
struct DenomkeysIterateContext *dic = cls;
|
||||||
struct TALER_EXCHANGEDB_DenominationKeyIssueInformation issue;
|
struct TALER_EXCHANGEDB_DenominationKeyIssueInformation issue;
|
||||||
int ret;
|
int ret;
|
||||||
|
char *rev;
|
||||||
|
struct TALER_MasterSignatureP msig;
|
||||||
|
struct TALER_MasterDenominationKeyRevocation rm;
|
||||||
|
int revoked;
|
||||||
|
|
||||||
|
if ( (strlen(filename) > strlen (".rev")) &&
|
||||||
|
(0 == strcmp (&filename[strlen(filename) - strlen (".rev")],
|
||||||
|
".rev")) )
|
||||||
|
return GNUNET_OK; /* ignore revocation files _here_; we'll try for them just below */
|
||||||
|
|
||||||
memset (&issue, 0, sizeof (issue));
|
memset (&issue, 0, sizeof (issue));
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
@ -198,9 +274,53 @@ denomkeys_iterate_keydir_iter (void *cls,
|
|||||||
filename);
|
filename);
|
||||||
return GNUNET_OK;
|
return GNUNET_OK;
|
||||||
}
|
}
|
||||||
|
/* check for revocation file */
|
||||||
|
GNUNET_asprintf (&rev,
|
||||||
|
"%s.rev",
|
||||||
|
filename);
|
||||||
|
revoked = GNUNET_NO;
|
||||||
|
if (GNUNET_YES == GNUNET_DISK_file_test (rev))
|
||||||
|
{
|
||||||
|
/* Check if revocation is valid... */
|
||||||
|
if (sizeof (msig) !=
|
||||||
|
GNUNET_DISK_fn_read (rev,
|
||||||
|
&msig,
|
||||||
|
sizeof (msig)))
|
||||||
|
{
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||||
|
_("Invalid revocation file `%s' found and ignored (bad size)\n"),
|
||||||
|
rev);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rm.purpose.purpose = htonl (TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED);
|
||||||
|
rm.purpose.size = htonl (sizeof (rm));
|
||||||
|
rm.h_denom_pub = issue.issue.properties.denom_hash;
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED,
|
||||||
|
&rm.purpose,
|
||||||
|
&msig.eddsa_signature,
|
||||||
|
&dic->master_pub->eddsa_pub))
|
||||||
|
{
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||||
|
_("Invalid revocation file `%s' found and ignored (bad signature)\n"),
|
||||||
|
rev);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||||
|
"Denomination key `%s' was revoked!\n",
|
||||||
|
filename);
|
||||||
|
revoked = GNUNET_YES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
GNUNET_free (rev);
|
||||||
ret = dic->it (dic->it_cls,
|
ret = dic->it (dic->it_cls,
|
||||||
dic->alias,
|
dic->alias,
|
||||||
&issue);
|
&issue,
|
||||||
|
revoked);
|
||||||
GNUNET_CRYPTO_rsa_private_key_free (issue.denom_priv.rsa_private_key);
|
GNUNET_CRYPTO_rsa_private_key_free (issue.denom_priv.rsa_private_key);
|
||||||
GNUNET_CRYPTO_rsa_public_key_free (issue.denom_pub.rsa_public_key);
|
GNUNET_CRYPTO_rsa_public_key_free (issue.denom_pub.rsa_public_key);
|
||||||
return ret;
|
return ret;
|
||||||
@ -238,6 +358,7 @@ denomkeys_iterate_topdir_iter (void *cls,
|
|||||||
* @param exchange_base_dir base directory for the exchange,
|
* @param exchange_base_dir base directory for the exchange,
|
||||||
* the signing keys must be in the #TALER_EXCHANGEDB_DIR_DENOMINATION_KEYS
|
* the signing keys must be in the #TALER_EXCHANGEDB_DIR_DENOMINATION_KEYS
|
||||||
* subdirectory
|
* subdirectory
|
||||||
|
* @param master_pub master public key (used to check revocations)
|
||||||
* @param it function to call on each denomination key found
|
* @param it function to call on each denomination key found
|
||||||
* @param it_cls closure for @a it
|
* @param it_cls closure for @a it
|
||||||
* @return -1 on error, 0 if no files were found, otherwise
|
* @return -1 on error, 0 if no files were found, otherwise
|
||||||
@ -247,6 +368,7 @@ denomkeys_iterate_topdir_iter (void *cls,
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
TALER_EXCHANGEDB_denomination_keys_iterate (const char *exchange_base_dir,
|
TALER_EXCHANGEDB_denomination_keys_iterate (const char *exchange_base_dir,
|
||||||
|
const struct TALER_MasterPublicKeyP *master_pub,
|
||||||
TALER_EXCHANGEDB_DenominationKeyIterator it,
|
TALER_EXCHANGEDB_DenominationKeyIterator it,
|
||||||
void *it_cls)
|
void *it_cls)
|
||||||
{
|
{
|
||||||
@ -257,6 +379,7 @@ TALER_EXCHANGEDB_denomination_keys_iterate (const char *exchange_base_dir,
|
|||||||
GNUNET_asprintf (&dir,
|
GNUNET_asprintf (&dir,
|
||||||
"%s" DIR_SEPARATOR_STR TALER_EXCHANGEDB_DIR_DENOMINATION_KEYS,
|
"%s" DIR_SEPARATOR_STR TALER_EXCHANGEDB_DIR_DENOMINATION_KEYS,
|
||||||
exchange_base_dir);
|
exchange_base_dir);
|
||||||
|
dic.master_pub = master_pub;
|
||||||
dic.it = it;
|
dic.it = it;
|
||||||
dic.it_cls = it_cls;
|
dic.it_cls = it_cls;
|
||||||
ret = GNUNET_DISK_directory_scan (dir,
|
ret = GNUNET_DISK_directory_scan (dir,
|
||||||
|
@ -160,8 +160,9 @@ TALER_EXCHANGEDB_signing_key_write (const char *exchange_base_dir,
|
|||||||
* @brief Iterator over denomination keys.
|
* @brief Iterator over denomination keys.
|
||||||
*
|
*
|
||||||
* @param cls closure
|
* @param cls closure
|
||||||
* @param dki the denomination key
|
|
||||||
* @param alias coin alias
|
* @param alias coin alias
|
||||||
|
* @param dki the denomination key
|
||||||
|
* @param was_revoked #GNUNET_YES if the @a dki was revoked and wallets should trigger /payback
|
||||||
* @return #GNUNET_OK to continue to iterate,
|
* @return #GNUNET_OK to continue to iterate,
|
||||||
* #GNUNET_NO to stop iteration with no error,
|
* #GNUNET_NO to stop iteration with no error,
|
||||||
* #GNUNET_SYSERR to abort iteration with error!
|
* #GNUNET_SYSERR to abort iteration with error!
|
||||||
@ -169,7 +170,8 @@ TALER_EXCHANGEDB_signing_key_write (const char *exchange_base_dir,
|
|||||||
typedef int
|
typedef int
|
||||||
(*TALER_EXCHANGEDB_DenominationKeyIterator)(void *cls,
|
(*TALER_EXCHANGEDB_DenominationKeyIterator)(void *cls,
|
||||||
const char *alias,
|
const char *alias,
|
||||||
const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki);
|
const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki,
|
||||||
|
int was_revoked);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -178,6 +180,7 @@ typedef int
|
|||||||
* @param exchange_base_dir base directory for the exchange,
|
* @param exchange_base_dir base directory for the exchange,
|
||||||
* the signing keys must be in the #TALER_EXCHANGEDB_DIR_DENOMINATION_KEYS
|
* the signing keys must be in the #TALER_EXCHANGEDB_DIR_DENOMINATION_KEYS
|
||||||
* subdirectory
|
* subdirectory
|
||||||
|
* @param master_pub master public key (used to check revocations)
|
||||||
* @param it function to call on each denomination key found
|
* @param it function to call on each denomination key found
|
||||||
* @param it_cls closure for @a it
|
* @param it_cls closure for @a it
|
||||||
* @return -1 on error, 0 if no files were found, otherwise
|
* @return -1 on error, 0 if no files were found, otherwise
|
||||||
@ -187,10 +190,30 @@ typedef int
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
TALER_EXCHANGEDB_denomination_keys_iterate (const char *exchange_base_dir,
|
TALER_EXCHANGEDB_denomination_keys_iterate (const char *exchange_base_dir,
|
||||||
|
const struct TALER_MasterPublicKeyP *master_pub,
|
||||||
TALER_EXCHANGEDB_DenominationKeyIterator it,
|
TALER_EXCHANGEDB_DenominationKeyIterator it,
|
||||||
void *it_cls);
|
void *it_cls);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark the given denomination key as revoked and request the wallets
|
||||||
|
* to initiate /payback.
|
||||||
|
*
|
||||||
|
* @param exchange_base_dir base directory for the exchange,
|
||||||
|
* the signing keys must be in the #TALER_EXCHANGEDB_DIR_DENOMINATION_KEYS
|
||||||
|
* subdirectory
|
||||||
|
* @param alias coin alias
|
||||||
|
* @param dki the denomination key to revoke
|
||||||
|
* @param mpriv master private key to sign
|
||||||
|
* @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
TALER_EXCHANGEDB_denomination_key_revoke (const char *exchange_base_dir,
|
||||||
|
const char *alias,
|
||||||
|
const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki,
|
||||||
|
const struct TALER_MasterPrivateKeyP *mpriv);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exports a denomination key to the given file.
|
* Exports a denomination key to the given file.
|
||||||
*
|
*
|
||||||
|
@ -83,6 +83,10 @@
|
|||||||
*/
|
*/
|
||||||
#define TALER_SIGNATURE_MASTER_WIRE_FEES 1028
|
#define TALER_SIGNATURE_MASTER_WIRE_FEES 1028
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The given revocation key was revoked and must no longer be used.
|
||||||
|
*/
|
||||||
|
#define TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED 1029
|
||||||
|
|
||||||
/*********************************************/
|
/*********************************************/
|
||||||
/* Exchange online signatures (with signing key) */
|
/* Exchange online signatures (with signing key) */
|
||||||
@ -937,6 +941,24 @@ struct TALER_MasterWireFeePS
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Message confirming that a denomination key was revoked.
|
||||||
|
*/
|
||||||
|
struct TALER_MasterDenominationKeyRevocation
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Purpose is #TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED.
|
||||||
|
*/
|
||||||
|
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hash of the denomination key.
|
||||||
|
*/
|
||||||
|
struct GNUNET_HashCode h_denom_pub;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Format used to generate the signature on a request to obtain
|
* @brief Format used to generate the signature on a request to obtain
|
||||||
* the wire transfer identifier associated with a deposit.
|
* the wire transfer identifier associated with a deposit.
|
||||||
|
Loading…
Reference in New Issue
Block a user