-fix recoup ugliness
This commit is contained in:
parent
3b6a0dd599
commit
1acc851deb
@ -1983,20 +1983,12 @@ check_recoup (struct CoinContext *cc,
|
||||
cc->qs = qs;
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
{
|
||||
struct TALER_RecoupRequestPS pr = {
|
||||
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP),
|
||||
.purpose.size = htonl (sizeof (pr)),
|
||||
.coin_pub = coin->coin_pub,
|
||||
.coin_blind = *coin_blind,
|
||||
.h_denom_pub = coin->denom_pub_hash
|
||||
};
|
||||
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_RECOUP,
|
||||
&pr,
|
||||
&coin_sig->eddsa_signature,
|
||||
&coin->coin_pub.eddsa_pub))
|
||||
TALER_wallet_recoup_verify (&coin->denom_pub_hash,
|
||||
coin_blind,
|
||||
amount,
|
||||
&coin->coin_pub,
|
||||
coin_sig))
|
||||
{
|
||||
TALER_ARL_report (report_bad_sig_losses,
|
||||
GNUNET_JSON_PACK (
|
||||
@ -2015,7 +2007,6 @@ check_recoup (struct CoinContext *cc,
|
||||
return GNUNET_SYSERR;
|
||||
return GNUNET_OK;
|
||||
}
|
||||
}
|
||||
ds = get_denomination_summary (cc,
|
||||
issue,
|
||||
&issue->denom_hash);
|
||||
|
@ -684,7 +684,7 @@ handle_reserve_out (void *cls,
|
||||
* @param coin_blind blinding factor used to blind the coin
|
||||
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
|
||||
*/
|
||||
static int
|
||||
static enum GNUNET_GenericReturnValue
|
||||
handle_recoup_by_reserve (
|
||||
void *cls,
|
||||
uint64_t rowid,
|
||||
@ -711,20 +711,12 @@ handle_recoup_by_reserve (
|
||||
ppr.last_reserve_recoup_serial_id = rowid + 1;
|
||||
/* We know that denom_pub matches denom_pub_hash because this
|
||||
is how the SQL statement joined the tables. */
|
||||
{
|
||||
struct TALER_RecoupRequestPS pr = {
|
||||
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP),
|
||||
.purpose.size = htonl (sizeof (pr)),
|
||||
.h_denom_pub = coin->denom_pub_hash,
|
||||
.coin_pub = coin->coin_pub,
|
||||
.coin_blind = *coin_blind
|
||||
};
|
||||
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_RECOUP,
|
||||
&pr,
|
||||
&coin_sig->eddsa_signature,
|
||||
&coin->coin_pub.eddsa_pub))
|
||||
TALER_wallet_recoup_verify (&coin->denom_pub_hash,
|
||||
coin_blind,
|
||||
amount,
|
||||
&coin->coin_pub,
|
||||
coin_sig))
|
||||
{
|
||||
TALER_ARL_report (report_bad_sig_losses,
|
||||
GNUNET_JSON_PACK (
|
||||
@ -740,7 +732,6 @@ handle_recoup_by_reserve (
|
||||
&total_bad_sig_loss,
|
||||
amount);
|
||||
}
|
||||
}
|
||||
|
||||
/* check that the coin was eligible for recoup!*/
|
||||
rev = GNUNET_CONTAINER_multihashmap_get (rc->revoked,
|
||||
|
@ -87,6 +87,7 @@ struct RecoupContext
|
||||
* Set by #recoup_transaction() to the amount that will be paid back
|
||||
*/
|
||||
struct TALER_Amount amount;
|
||||
const struct TALER_Amount *requested_amount;
|
||||
|
||||
/**
|
||||
* Set by #recoup_transaction to the timestamp when the recoup
|
||||
@ -234,6 +235,15 @@ recoup_transaction (void *cls,
|
||||
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
|
||||
tl);
|
||||
pc->now = GNUNET_TIME_timestamp_get ();
|
||||
if (0 != TALER_amount_cmp (&pc->amount,
|
||||
pc->requested_amount))
|
||||
{
|
||||
*mhd_ret = TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_CONFLICT,
|
||||
TALER_EC_EXCHANGE_GENERIC_INSUFFICIENT_FUNDS,
|
||||
TALER_amount2s (&pc->amount));
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
}
|
||||
|
||||
/* add coin to list of wire transfers for recoup */
|
||||
if (pc->refreshed)
|
||||
@ -284,6 +294,7 @@ recoup_transaction (void *cls,
|
||||
* @param coin information about the coin
|
||||
* @param coin_bks blinding data of the coin (to be checked)
|
||||
* @param coin_sig signature of the coin
|
||||
* @param requested_amount requested amount to be recouped
|
||||
* @param refreshed true if the coin was refreshed
|
||||
* @return MHD result code
|
||||
*/
|
||||
@ -293,6 +304,7 @@ verify_and_execute_recoup (
|
||||
const struct TALER_CoinPublicInfo *coin,
|
||||
const union TALER_DenominationBlindingKeyP *coin_bks,
|
||||
const struct TALER_CoinSpendSignatureP *coin_sig,
|
||||
const struct TALER_Amount *requested_amount,
|
||||
bool refreshed)
|
||||
{
|
||||
struct RecoupContext pc;
|
||||
@ -352,28 +364,19 @@ verify_and_execute_recoup (
|
||||
}
|
||||
|
||||
/* check recoup request signature */
|
||||
{
|
||||
struct TALER_RecoupRequestPS pr = {
|
||||
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP),
|
||||
.purpose.size = htonl (sizeof (pr)),
|
||||
.coin_pub = coin->coin_pub,
|
||||
.h_denom_pub = coin->denom_pub_hash,
|
||||
.coin_blind = *coin_bks
|
||||
};
|
||||
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_RECOUP,
|
||||
&pr,
|
||||
&coin_sig->eddsa_signature,
|
||||
&coin->coin_pub.eddsa_pub))
|
||||
TALER_wallet_recoup_verify (&coin->denom_pub_hash,
|
||||
coin_bks,
|
||||
requested_amount,
|
||||
&coin->coin_pub,
|
||||
coin_sig))
|
||||
{
|
||||
TALER_LOG_WARNING ("Invalid signature on recoup request\n");
|
||||
GNUNET_break_op (0);
|
||||
return TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_FORBIDDEN,
|
||||
TALER_EC_EXCHANGE_RECOUP_SIGNATURE_INVALID,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
void *coin_ev;
|
||||
@ -404,6 +407,7 @@ verify_and_execute_recoup (
|
||||
pc.coin_bks = coin_bks;
|
||||
pc.coin = coin;
|
||||
pc.refreshed = refreshed;
|
||||
pc.requested_amount = requested_amount;
|
||||
|
||||
{
|
||||
MHD_RESULT mhd_ret = MHD_NO;
|
||||
@ -552,6 +556,7 @@ TEH_handler_recoup (struct MHD_Connection *connection,
|
||||
&coin,
|
||||
&coin_bks,
|
||||
&coin_sig,
|
||||
&amount,
|
||||
refreshed);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return res;
|
||||
|
@ -697,8 +697,6 @@ CREATE INDEX IF NOT EXISTS revolving_work_shards_index
|
||||
-- Stored procedures
|
||||
|
||||
|
||||
DROP FUNCTION IF EXISTS exchange_do_withdraw(bigint,integer,bytea,bytea,bytea,bytea,bytea,bigint,bigint) ;
|
||||
|
||||
CREATE OR REPLACE FUNCTION exchange_do_withdraw(
|
||||
IN amount_val INT8,
|
||||
IN amount_frac INT4,
|
||||
@ -857,9 +855,6 @@ COMMENT ON FUNCTION exchange_do_withdraw(INT8, INT4, BYTEA, BYTEA, BYTEA, BYTEA,
|
||||
|
||||
|
||||
|
||||
DROP FUNCTION IF EXISTS exchange_do_withdraw_limit_check(bigint,bigint,bigint,int) ;
|
||||
|
||||
|
||||
CREATE OR REPLACE FUNCTION exchange_do_withdraw_limit_check(
|
||||
IN ruuid INT8,
|
||||
IN start_time INT8,
|
||||
|
@ -3246,8 +3246,8 @@ postgres_get_denomination_info (
|
||||
rs);
|
||||
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
|
||||
return qs;
|
||||
issue->properties.purpose.size = htonl (sizeof (struct
|
||||
TALER_DenominationKeyValidityPS));
|
||||
issue->properties.purpose.size
|
||||
= htonl (sizeof (struct TALER_DenominationKeyValidityPS));
|
||||
issue->properties.purpose.purpose = htonl (
|
||||
TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY);
|
||||
issue->properties.denom_hash = *denom_pub_hash;
|
||||
|
@ -238,18 +238,21 @@ create_denom_key_pair (unsigned int size,
|
||||
sizeof (struct TALER_EXCHANGEDB_DenominationKey));
|
||||
dki.denom_pub = dkp->pub;
|
||||
dki.issue.properties.start = GNUNET_TIME_timestamp_hton (now);
|
||||
dki.issue.properties.expire_withdraw = GNUNET_TIME_timestamp_hton
|
||||
dki.issue.properties.expire_withdraw
|
||||
= GNUNET_TIME_timestamp_hton
|
||||
(GNUNET_TIME_absolute_to_timestamp
|
||||
(GNUNET_TIME_absolute_add (
|
||||
now.abs_time,
|
||||
GNUNET_TIME_UNIT_HOURS)));
|
||||
dki.issue.properties.expire_deposit = GNUNET_TIME_timestamp_hton (
|
||||
dki.issue.properties.expire_deposit
|
||||
= GNUNET_TIME_timestamp_hton (
|
||||
GNUNET_TIME_absolute_to_timestamp
|
||||
(GNUNET_TIME_absolute_add
|
||||
(now.abs_time,
|
||||
GNUNET_TIME_relative_multiply (
|
||||
GNUNET_TIME_UNIT_HOURS, 2))));
|
||||
dki.issue.properties.expire_legal = GNUNET_TIME_timestamp_hton (
|
||||
dki.issue.properties.expire_legal
|
||||
= GNUNET_TIME_timestamp_hton (
|
||||
GNUNET_TIME_absolute_to_timestamp
|
||||
(GNUNET_TIME_absolute_add
|
||||
(now.abs_time,
|
||||
@ -276,6 +279,8 @@ create_denom_key_pair (unsigned int size,
|
||||
destroy_denom_key_pair (dkp);
|
||||
return NULL;
|
||||
}
|
||||
memset (&issue2, 0, sizeof (issue2));
|
||||
plugin->commit (plugin->cls);
|
||||
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
|
||||
plugin->get_denomination_info (plugin->cls,
|
||||
&dki.issue.properties.denom_hash,
|
||||
|
@ -1738,6 +1738,63 @@ TALER_wallet_link_verify (
|
||||
const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
|
||||
const struct TALER_CoinSpendSignatureP *coin_sig);
|
||||
|
||||
|
||||
/**
|
||||
* Sign link data.
|
||||
*
|
||||
* @param h_denom_pub hash of the denomiantion public key of the new coin
|
||||
* @param transfer_pub transfer public key
|
||||
* @param coin_ev coin envelope
|
||||
* @param coin_ev_size number of bytes in @a coin_ev
|
||||
* @param old_coin_priv private key to sign with
|
||||
* @param[out] coin_sig resulting signature
|
||||
*/
|
||||
void
|
||||
TALER_wallet_link_sign (const struct TALER_DenominationHash *h_denom_pub,
|
||||
const struct TALER_TransferPublicKeyP *transfer_pub,
|
||||
const void *coin_ev,
|
||||
size_t coin_ev_size,
|
||||
const struct TALER_CoinSpendPrivateKeyP *old_coin_priv,
|
||||
struct TALER_CoinSpendSignatureP *coin_sig);
|
||||
|
||||
|
||||
/**
|
||||
* Verify recoup signature.
|
||||
*
|
||||
* @param h_denom_pub hash of the denomiantion public key of the coin
|
||||
* @param coin_bks blinding factor used when withdrawing the coin
|
||||
* @param requested_amount amount that is left to be recouped
|
||||
* @param coin_pub coin key of the coin to be recouped
|
||||
* @param coin_sig resulting signature
|
||||
* @return #GNUNET_OK if the signature is valid
|
||||
*/
|
||||
enum GNUNET_GenericReturnValue
|
||||
TALER_wallet_recoup_verify (
|
||||
const struct TALER_DenominationHash *h_denom_pub,
|
||||
const union TALER_DenominationBlindingKeyP *coin_bks,
|
||||
const struct TALER_Amount *requested_amount,
|
||||
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
||||
const struct TALER_CoinSpendSignatureP *coin_sig);
|
||||
|
||||
|
||||
/**
|
||||
* Create recoup signature.
|
||||
*
|
||||
* @param h_denom_pub hash of the denomiantion public key of the coin
|
||||
* @param coin_bks blinding factor used when withdrawing the coin
|
||||
* @param requested_amount amount that is left to be recouped
|
||||
* @param coin_priv coin key of the coin to be recouped
|
||||
* @param coin_sig resulting signature
|
||||
*/
|
||||
void
|
||||
TALER_wallet_recoup_sign (
|
||||
const struct TALER_DenominationHash *h_denom_pub,
|
||||
const union TALER_DenominationBlindingKeyP *coin_bks,
|
||||
const struct TALER_Amount *requested_amount,
|
||||
const struct TALER_CoinSpendPrivateKeyP *coin_priv,
|
||||
struct TALER_CoinSpendSignatureP *coin_sig);
|
||||
|
||||
|
||||
/* ********************* offline signing ************************** */
|
||||
|
||||
|
||||
|
@ -1496,11 +1496,6 @@ struct TALER_RecoupRequestPS
|
||||
*/
|
||||
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
|
||||
|
||||
/**
|
||||
* Public key of the coin to be refunded.
|
||||
*/
|
||||
struct TALER_CoinSpendPublicKeyP coin_pub;
|
||||
|
||||
/**
|
||||
* Hash of the (revoked) denomination public key of the coin.
|
||||
*/
|
||||
@ -1510,6 +1505,12 @@ struct TALER_RecoupRequestPS
|
||||
* Blinding factor that was used to withdraw the coin.
|
||||
*/
|
||||
union TALER_DenominationBlindingKeyP coin_blind;
|
||||
|
||||
/**
|
||||
* How much of the coin's value will be recouped?
|
||||
*/
|
||||
struct TALER_AmountNBO recoup_amount;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -688,17 +688,16 @@ TALER_EXCHANGE_verify_coin_history (
|
||||
.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP),
|
||||
.coin_pub = *coin_pub
|
||||
};
|
||||
struct TALER_RecoupRequestPS rr = {
|
||||
.purpose.size = htonl (sizeof (pc)),
|
||||
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP),
|
||||
.coin_pub = *coin_pub
|
||||
};
|
||||
union TALER_DenominationBlindingKeyP coin_bks;
|
||||
struct TALER_Amount recoup_amount;
|
||||
struct TALER_ExchangePublicKeyP exchange_pub;
|
||||
struct TALER_ExchangeSignatureP exchange_sig;
|
||||
struct TALER_CoinSpendSignatureP coin_sig;
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
TALER_JSON_spec_amount_any_nbo ("amount",
|
||||
&pc.recoup_amount),
|
||||
TALER_JSON_spec_amount_any ("amount",
|
||||
&recoup_amount),
|
||||
GNUNET_JSON_spec_fixed_auto ("exchange_sig",
|
||||
&exchange_sig),
|
||||
GNUNET_JSON_spec_fixed_auto ("exchange_pub",
|
||||
@ -708,9 +707,9 @@ TALER_EXCHANGE_verify_coin_history (
|
||||
GNUNET_JSON_spec_fixed_auto ("coin_sig",
|
||||
&coin_sig),
|
||||
GNUNET_JSON_spec_fixed_auto ("coin_blind",
|
||||
&rr.coin_blind),
|
||||
&coin_bks),
|
||||
GNUNET_JSON_spec_fixed_auto ("h_denom_pub",
|
||||
&rr.h_denom_pub),
|
||||
h_denom_pub),
|
||||
GNUNET_JSON_spec_timestamp_nbo ("timestamp",
|
||||
&pc.timestamp),
|
||||
GNUNET_JSON_spec_end ()
|
||||
@ -736,15 +735,15 @@ TALER_EXCHANGE_verify_coin_history (
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_RECOUP,
|
||||
&rr,
|
||||
&coin_sig.eddsa_signature,
|
||||
&coin_pub->eddsa_pub))
|
||||
TALER_wallet_recoup_verify (h_denom_pub,
|
||||
&coin_bks,
|
||||
&recoup_amount,
|
||||
coin_pub,
|
||||
&coin_sig))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
*h_denom_pub = rr.h_denom_pub;
|
||||
add = GNUNET_YES;
|
||||
}
|
||||
else if (0 == strcasecmp (type,
|
||||
@ -758,17 +757,16 @@ TALER_EXCHANGE_verify_coin_history (
|
||||
TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH),
|
||||
.coin_pub = *coin_pub
|
||||
};
|
||||
struct TALER_RecoupRequestPS rr = {
|
||||
.purpose.size = htonl (sizeof (pc)),
|
||||
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP),
|
||||
.coin_pub = *coin_pub
|
||||
};
|
||||
union TALER_DenominationBlindingKeyP coin_bks;
|
||||
struct TALER_Amount recoup_amount;
|
||||
struct TALER_ExchangePublicKeyP exchange_pub;
|
||||
struct TALER_ExchangeSignatureP exchange_sig;
|
||||
struct TALER_CoinSpendSignatureP coin_sig;
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
TALER_JSON_spec_amount_any_nbo ("amount",
|
||||
&pc.recoup_amount),
|
||||
TALER_JSON_spec_amount_any ("amount",
|
||||
&recoup_amount),
|
||||
GNUNET_JSON_spec_fixed_auto ("exchange_sig",
|
||||
&exchange_sig),
|
||||
GNUNET_JSON_spec_fixed_auto ("exchange_pub",
|
||||
@ -778,9 +776,9 @@ TALER_EXCHANGE_verify_coin_history (
|
||||
GNUNET_JSON_spec_fixed_auto ("old_coin_pub",
|
||||
&pc.old_coin_pub),
|
||||
GNUNET_JSON_spec_fixed_auto ("coin_blind",
|
||||
&rr.coin_blind),
|
||||
&coin_bks),
|
||||
GNUNET_JSON_spec_fixed_auto ("h_denom_pub",
|
||||
&rr.h_denom_pub),
|
||||
h_denom_pub),
|
||||
GNUNET_JSON_spec_timestamp_nbo ("timestamp",
|
||||
&pc.timestamp),
|
||||
GNUNET_JSON_spec_end ()
|
||||
@ -807,15 +805,15 @@ TALER_EXCHANGE_verify_coin_history (
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_RECOUP,
|
||||
&rr,
|
||||
&coin_sig.eddsa_signature,
|
||||
&coin_pub->eddsa_pub))
|
||||
TALER_wallet_recoup_verify (h_denom_pub,
|
||||
&coin_bks,
|
||||
&recoup_amount,
|
||||
coin_pub,
|
||||
&coin_sig))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
*h_denom_pub = rr.h_denom_pub;
|
||||
add = GNUNET_YES;
|
||||
}
|
||||
else if (0 == strcasecmp (type,
|
||||
|
@ -95,7 +95,7 @@ struct TALER_EXCHANGE_RecoupHandle
|
||||
* @return #GNUNET_OK if the signature is valid and we called the callback;
|
||||
* #GNUNET_SYSERR if not (callback must still be called)
|
||||
*/
|
||||
static int
|
||||
static enum GNUNET_GenericReturnValue
|
||||
process_recoup_response (const struct TALER_EXCHANGE_RecoupHandle *ph,
|
||||
const json_t *json)
|
||||
{
|
||||
@ -312,8 +312,8 @@ TALER_EXCHANGE_recoup (struct TALER_EXCHANGE_Handle *exchange,
|
||||
{
|
||||
struct TALER_EXCHANGE_RecoupHandle *ph;
|
||||
struct GNUNET_CURL_Context *ctx;
|
||||
struct TALER_RecoupRequestPS pr;
|
||||
struct TALER_CoinSpendSignatureP coin_sig;
|
||||
struct TALER_CoinSpendPublicKeyP coin_pub;
|
||||
struct TALER_DenominationHash h_denom_pub;
|
||||
json_t *recoup_obj;
|
||||
CURL *eh;
|
||||
@ -321,17 +321,15 @@ TALER_EXCHANGE_recoup (struct TALER_EXCHANGE_Handle *exchange,
|
||||
|
||||
GNUNET_assert (GNUNET_YES ==
|
||||
TEAH_handle_is_ready (exchange));
|
||||
pr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP);
|
||||
pr.purpose.size = htonl (sizeof (struct TALER_RecoupRequestPS));
|
||||
GNUNET_CRYPTO_eddsa_key_get_public (&ps->coin_priv.eddsa_priv,
|
||||
&pr.coin_pub.eddsa_pub);
|
||||
&coin_pub.eddsa_pub);
|
||||
TALER_denom_pub_hash (&pk->key,
|
||||
&h_denom_pub);
|
||||
pr.h_denom_pub = pk->h_key;
|
||||
pr.coin_blind = ps->blinding_key;
|
||||
GNUNET_CRYPTO_eddsa_sign (&ps->coin_priv.eddsa_priv,
|
||||
&pr,
|
||||
&coin_sig.eddsa_signature);
|
||||
TALER_wallet_recoup_sign (&h_denom_pub,
|
||||
&ps->blinding_key,
|
||||
amount,
|
||||
&ps->coin_priv,
|
||||
&coin_sig);
|
||||
recoup_obj = GNUNET_JSON_PACK (
|
||||
GNUNET_JSON_pack_data_auto ("denom_pub_hash",
|
||||
&h_denom_pub),
|
||||
@ -349,9 +347,9 @@ TALER_EXCHANGE_recoup (struct TALER_EXCHANGE_Handle *exchange,
|
||||
char pub_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2];
|
||||
char *end;
|
||||
|
||||
end = GNUNET_STRINGS_data_to_string (&pr.coin_pub,
|
||||
sizeof (struct
|
||||
TALER_CoinSpendPublicKeyP),
|
||||
end = GNUNET_STRINGS_data_to_string (
|
||||
&coin_pub,
|
||||
sizeof (struct TALER_CoinSpendPublicKeyP),
|
||||
pub_str,
|
||||
sizeof (pub_str));
|
||||
*end = '\0';
|
||||
@ -362,7 +360,7 @@ TALER_EXCHANGE_recoup (struct TALER_EXCHANGE_Handle *exchange,
|
||||
}
|
||||
|
||||
ph = GNUNET_new (struct TALER_EXCHANGE_RecoupHandle);
|
||||
ph->coin_pub = pr.coin_pub;
|
||||
ph->coin_pub = coin_pub;
|
||||
ph->exchange = exchange;
|
||||
ph->pk = *pk;
|
||||
memset (&ph->pk.key,
|
||||
|
@ -855,7 +855,7 @@ run (void *cls,
|
||||
MHD_HTTP_OK,
|
||||
"recoup-withdraw-coin-2a",
|
||||
NULL,
|
||||
NULL),
|
||||
"EUR:0.5"),
|
||||
TALER_TESTING_cmd_deposit ("recoup-deposit-revoked",
|
||||
"recoup-withdraw-coin-2b",
|
||||
0,
|
||||
|
@ -139,7 +139,7 @@ run (void *cls,
|
||||
MHD_HTTP_GONE,
|
||||
"refresh-reveal-1#0",
|
||||
"refresh-melt-1",
|
||||
NULL),
|
||||
"EUR:0.1"),
|
||||
/* Make refreshed coin invalid */
|
||||
TALER_TESTING_cmd_revoke ("revoke-2-EUR:5",
|
||||
MHD_HTTP_OK,
|
||||
@ -155,44 +155,44 @@ run (void *cls,
|
||||
MHD_HTTP_CONFLICT,
|
||||
"withdraw-revocation-coin-2",
|
||||
NULL,
|
||||
NULL),
|
||||
"EUR:0.1"),
|
||||
/* Refund coin to original coin */
|
||||
TALER_TESTING_cmd_recoup ("recoup-1a",
|
||||
MHD_HTTP_OK,
|
||||
"refresh-reveal-1#0",
|
||||
"refresh-melt-1",
|
||||
NULL),
|
||||
"EUR:1"),
|
||||
TALER_TESTING_cmd_recoup ("recoup-1b",
|
||||
MHD_HTTP_OK,
|
||||
"refresh-reveal-1#1",
|
||||
"refresh-melt-1",
|
||||
NULL),
|
||||
"EUR:1"),
|
||||
TALER_TESTING_cmd_recoup ("recoup-1c",
|
||||
MHD_HTTP_OK,
|
||||
"refresh-reveal-1#2",
|
||||
"refresh-melt-1",
|
||||
NULL),
|
||||
"EUR:1"),
|
||||
/* Repeat recoup to test idempotency */
|
||||
TALER_TESTING_cmd_recoup ("recoup-1c",
|
||||
MHD_HTTP_OK,
|
||||
"refresh-reveal-1#2",
|
||||
"refresh-melt-1",
|
||||
NULL),
|
||||
"EUR:1"),
|
||||
TALER_TESTING_cmd_recoup ("recoup-1c",
|
||||
MHD_HTTP_OK,
|
||||
"refresh-reveal-1#2",
|
||||
"refresh-melt-1",
|
||||
NULL),
|
||||
"EUR:1"),
|
||||
TALER_TESTING_cmd_recoup ("recoup-1c",
|
||||
MHD_HTTP_OK,
|
||||
"refresh-reveal-1#2",
|
||||
"refresh-melt-1",
|
||||
NULL),
|
||||
"EUR:1"),
|
||||
TALER_TESTING_cmd_recoup ("recoup-1c",
|
||||
MHD_HTTP_OK,
|
||||
"refresh-reveal-1#2",
|
||||
"refresh-melt-1",
|
||||
NULL),
|
||||
"EUR:1"),
|
||||
/* Now we have EUR:3.83 EUR back after 3x EUR:1 in recoups */
|
||||
/* Melt original coin AGAIN, but only create one 0.1 EUR coin;
|
||||
This costs EUR:0.03 in refresh and EUR:01 in withdraw fees,
|
||||
@ -223,7 +223,7 @@ run (void *cls,
|
||||
MHD_HTTP_OK,
|
||||
"refresh-reveal-2",
|
||||
"refresh-melt-2",
|
||||
NULL),
|
||||
"EUR:0.1"),
|
||||
/* Due to recoup, original coin is now at EUR:3.79 */
|
||||
/* Refund original (now zombie) coin to reserve */
|
||||
TALER_TESTING_cmd_recoup ("recoup-3",
|
||||
|
@ -155,4 +155,51 @@ TALER_wallet_link_verify (
|
||||
}
|
||||
|
||||
|
||||
enum GNUNET_GenericReturnValue
|
||||
TALER_wallet_recoup_verify (
|
||||
const struct TALER_DenominationHash *h_denom_pub,
|
||||
const union TALER_DenominationBlindingKeyP *coin_bks,
|
||||
const struct TALER_Amount *requested_amount,
|
||||
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
||||
const struct TALER_CoinSpendSignatureP *coin_sig)
|
||||
{
|
||||
struct TALER_RecoupRequestPS pr = {
|
||||
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP),
|
||||
.purpose.size = htonl (sizeof (pr)),
|
||||
.h_denom_pub = *h_denom_pub,
|
||||
.coin_blind = *coin_bks
|
||||
};
|
||||
|
||||
TALER_amount_hton (&pr.recoup_amount,
|
||||
requested_amount);
|
||||
return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_RECOUP,
|
||||
&pr,
|
||||
&coin_sig->eddsa_signature,
|
||||
&coin_pub->eddsa_pub);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TALER_wallet_recoup_sign (
|
||||
const struct TALER_DenominationHash *h_denom_pub,
|
||||
const union TALER_DenominationBlindingKeyP *coin_bks,
|
||||
const struct TALER_Amount *requested_amount,
|
||||
const struct TALER_CoinSpendPrivateKeyP *coin_priv,
|
||||
struct TALER_CoinSpendSignatureP *coin_sig)
|
||||
{
|
||||
struct TALER_RecoupRequestPS pr = {
|
||||
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP),
|
||||
.purpose.size = htonl (sizeof (struct TALER_RecoupRequestPS)),
|
||||
.h_denom_pub = *h_denom_pub,
|
||||
.coin_blind = *coin_bks
|
||||
};
|
||||
|
||||
TALER_amount_hton (&pr.recoup_amount,
|
||||
requested_amount);
|
||||
GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv,
|
||||
&pr,
|
||||
&coin_sig->eddsa_signature);
|
||||
}
|
||||
|
||||
|
||||
/* end of wallet_signatures.c */
|
||||
|
Loading…
Reference in New Issue
Block a user