-fixes to tests, and half-baked fixes for CS-/link (still fails)
This commit is contained in:
parent
d58d89dcab
commit
532d4ad0dc
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
This file is part of TALER
|
This file is part of TALER
|
||||||
Copyright (C) 2014-2019 Taler Systems SA
|
Copyright (C) 2014-2019, 2022 Taler Systems SA
|
||||||
|
|
||||||
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 Affero General Public License as published by the Free Software
|
terms of the GNU Affero General Public License as published by the Free Software
|
||||||
@ -86,6 +86,10 @@ handle_link_data (void *cls,
|
|||||||
&pos->denom_pub),
|
&pos->denom_pub),
|
||||||
TALER_JSON_pack_blinded_denom_sig ("ev_sig",
|
TALER_JSON_pack_blinded_denom_sig ("ev_sig",
|
||||||
&pos->ev_sig),
|
&pos->ev_sig),
|
||||||
|
GNUNET_JSON_pack_uint64 ("coin_idx",
|
||||||
|
pos->coin_refresh_offset),
|
||||||
|
TALER_JSON_pack_exchange_withdraw_values ("ewv",
|
||||||
|
&pos->alg_values),
|
||||||
GNUNET_JSON_pack_data_auto ("link_sig",
|
GNUNET_JSON_pack_data_auto ("link_sig",
|
||||||
&pos->orig_coin_link_sig));
|
&pos->orig_coin_link_sig));
|
||||||
if ( (NULL == obj) ||
|
if ( (NULL == obj) ||
|
||||||
|
@ -105,7 +105,10 @@ struct RevealContext
|
|||||||
/**
|
/**
|
||||||
* Array of information about fresh coins being revealed.
|
* Array of information about fresh coins being revealed.
|
||||||
*/
|
*/
|
||||||
const struct TALER_EXCHANGEDB_RefreshRevealedCoin *rrcs;
|
/* FIXME: const would be nicer here, but we initalize
|
||||||
|
the 'alg_values' in the verification
|
||||||
|
routine; suboptimal to be fixed... */
|
||||||
|
struct TALER_EXCHANGEDB_RefreshRevealedCoin *rrcs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Envelopes to be signed.
|
* Envelopes to be signed.
|
||||||
@ -141,7 +144,6 @@ check_commitment (struct RevealContext *rctx,
|
|||||||
struct MHD_Connection *connection,
|
struct MHD_Connection *connection,
|
||||||
MHD_RESULT *mhd_ret)
|
MHD_RESULT *mhd_ret)
|
||||||
{
|
{
|
||||||
struct TALER_ExchangeWithdrawValues alg_values[rctx->num_fresh_coins];
|
|
||||||
struct TALER_CsNonce nonces[rctx->num_fresh_coins];
|
struct TALER_CsNonce nonces[rctx->num_fresh_coins];
|
||||||
unsigned int aoff = 0;
|
unsigned int aoff = 0;
|
||||||
|
|
||||||
@ -184,8 +186,10 @@ check_commitment (struct RevealContext *rctx,
|
|||||||
for (unsigned int j = 0; j<rctx->num_fresh_coins; j++)
|
for (unsigned int j = 0; j<rctx->num_fresh_coins; j++)
|
||||||
{
|
{
|
||||||
const struct TALER_DenominationPublicKey *dk = &rctx->dks[j]->denom_pub;
|
const struct TALER_DenominationPublicKey *dk = &rctx->dks[j]->denom_pub;
|
||||||
|
struct TALER_ExchangeWithdrawValues *alg_values
|
||||||
|
= &rctx->rrcs[j].exchange_vals;
|
||||||
|
|
||||||
alg_values[j].cipher = dk->cipher;
|
alg_values->cipher = dk->cipher;
|
||||||
switch (dk->cipher)
|
switch (dk->cipher)
|
||||||
{
|
{
|
||||||
case TALER_DENOMINATION_INVALID:
|
case TALER_DENOMINATION_INVALID:
|
||||||
@ -200,7 +204,7 @@ check_commitment (struct RevealContext *rctx,
|
|||||||
ec = TEH_keys_denomination_cs_r_pub (
|
ec = TEH_keys_denomination_cs_r_pub (
|
||||||
&rctx->rrcs[j].h_denom_pub,
|
&rctx->rrcs[j].h_denom_pub,
|
||||||
&nonces[aoff],
|
&nonces[aoff],
|
||||||
&alg_values[j].details.cs_values.r_pub_pair);
|
&alg_values->details.cs_values.r_pub_pair);
|
||||||
if (TALER_EC_NONE != ec)
|
if (TALER_EC_NONE != ec)
|
||||||
{
|
{
|
||||||
*mhd_ret = TALER_MHD_reply_with_error (connection,
|
*mhd_ret = TALER_MHD_reply_with_error (connection,
|
||||||
@ -251,12 +255,13 @@ check_commitment (struct RevealContext *rctx,
|
|||||||
aoff = 0;
|
aoff = 0;
|
||||||
for (unsigned int j = 0; j<rctx->num_fresh_coins; j++)
|
for (unsigned int j = 0; j<rctx->num_fresh_coins; j++)
|
||||||
{
|
{
|
||||||
const struct TALER_DenominationPublicKey *dk =
|
const struct TALER_DenominationPublicKey *dk
|
||||||
&rctx->dks[j]->denom_pub;
|
= &rctx->dks[j]->denom_pub;
|
||||||
struct TALER_RefreshCoinData *rcd = &rce->new_coins[j];
|
struct TALER_RefreshCoinData *rcd = &rce->new_coins[j];
|
||||||
struct TALER_CoinSpendPrivateKeyP coin_priv;
|
struct TALER_CoinSpendPrivateKeyP coin_priv;
|
||||||
union TALER_DenominationBlindingKeyP bks;
|
union TALER_DenominationBlindingKeyP bks;
|
||||||
const struct TALER_ExchangeWithdrawValues *alg_value = &alg_values[j];
|
const struct TALER_ExchangeWithdrawValues *alg_value
|
||||||
|
= &rctx->rrcs[j].exchange_vals;
|
||||||
struct TALER_PlanchetDetail pd;
|
struct TALER_PlanchetDetail pd;
|
||||||
struct TALER_CoinPubHash c_hash;
|
struct TALER_CoinPubHash c_hash;
|
||||||
struct TALER_PlanchetSecretsP ps;
|
struct TALER_PlanchetSecretsP ps;
|
||||||
|
@ -377,6 +377,7 @@ CREATE TABLE IF NOT EXISTS refresh_revealed_coins
|
|||||||
,coin_ev BYTEA NOT NULL -- UNIQUE
|
,coin_ev BYTEA NOT NULL -- UNIQUE
|
||||||
,h_coin_ev BYTEA NOT NULL CHECK(LENGTH(h_coin_ev)=64) -- UNIQUE
|
,h_coin_ev BYTEA NOT NULL CHECK(LENGTH(h_coin_ev)=64) -- UNIQUE
|
||||||
,ev_sig BYTEA NOT NULL
|
,ev_sig BYTEA NOT NULL
|
||||||
|
,ewv BYTEA NOT NULL
|
||||||
-- ,PRIMARY KEY (melt_serial_id, freshcoin_index) -- done per shard
|
-- ,PRIMARY KEY (melt_serial_id, freshcoin_index) -- done per shard
|
||||||
)
|
)
|
||||||
PARTITION BY HASH (melt_serial_id);
|
PARTITION BY HASH (melt_serial_id);
|
||||||
@ -390,6 +391,8 @@ COMMENT ON COLUMN refresh_revealed_coins.freshcoin_index
|
|||||||
IS 'index of the fresh coin being created (one melt operation may result in multiple fresh coins)';
|
IS 'index of the fresh coin being created (one melt operation may result in multiple fresh coins)';
|
||||||
COMMENT ON COLUMN refresh_revealed_coins.coin_ev
|
COMMENT ON COLUMN refresh_revealed_coins.coin_ev
|
||||||
IS 'envelope of the new coin to be signed';
|
IS 'envelope of the new coin to be signed';
|
||||||
|
COMMENT ON COLUMN refresh_revealed_coins.ewv
|
||||||
|
IS 'exchange contributed values in the creation of the fresh coin (see /csr)';
|
||||||
COMMENT ON COLUMN refresh_revealed_coins.h_coin_ev
|
COMMENT ON COLUMN refresh_revealed_coins.h_coin_ev
|
||||||
IS 'hash of the envelope of the new coin to be signed (for lookups)';
|
IS 'hash of the envelope of the new coin to be signed (for lookups)';
|
||||||
COMMENT ON COLUMN refresh_revealed_coins.ev_sig
|
COMMENT ON COLUMN refresh_revealed_coins.ev_sig
|
||||||
|
@ -440,6 +440,8 @@ irbt_cb_table_refresh_revealed_coins (
|
|||||||
GNUNET_PQ_query_param_auto_from_type (&h_coin_ev),
|
GNUNET_PQ_query_param_auto_from_type (&h_coin_ev),
|
||||||
TALER_PQ_query_param_blinded_denom_sig (
|
TALER_PQ_query_param_blinded_denom_sig (
|
||||||
&td->details.refresh_revealed_coins.ev_sig),
|
&td->details.refresh_revealed_coins.ev_sig),
|
||||||
|
TALER_PQ_query_param_exchange_withdraw_values (
|
||||||
|
&td->details.refresh_revealed_coins.ewv),
|
||||||
GNUNET_PQ_query_param_uint64 (
|
GNUNET_PQ_query_param_uint64 (
|
||||||
&td->details.refresh_revealed_coins.denominations_serial),
|
&td->details.refresh_revealed_coins.denominations_serial),
|
||||||
GNUNET_PQ_query_param_uint64 (
|
GNUNET_PQ_query_param_uint64 (
|
||||||
|
@ -790,6 +790,9 @@ lrbt_cb_table_refresh_revealed_coins (void *cls,
|
|||||||
TALER_PQ_result_spec_blinded_denom_sig (
|
TALER_PQ_result_spec_blinded_denom_sig (
|
||||||
"ev_sig",
|
"ev_sig",
|
||||||
&td.details.refresh_revealed_coins.ev_sig),
|
&td.details.refresh_revealed_coins.ev_sig),
|
||||||
|
TALER_PQ_result_spec_exchange_withdraw_values (
|
||||||
|
"ewv",
|
||||||
|
&td.details.refresh_revealed_coins.ewv),
|
||||||
GNUNET_PQ_result_spec_uint64 (
|
GNUNET_PQ_result_spec_uint64 (
|
||||||
"denominations_serial",
|
"denominations_serial",
|
||||||
&td.details.refresh_revealed_coins.denominations_serial),
|
&td.details.refresh_revealed_coins.denominations_serial),
|
||||||
|
@ -891,13 +891,14 @@ prepare_statements (struct PostgresClosure *pg)
|
|||||||
",link_sig "
|
",link_sig "
|
||||||
",denominations_serial "
|
",denominations_serial "
|
||||||
",coin_ev"
|
",coin_ev"
|
||||||
|
",ewv"
|
||||||
",h_coin_ev"
|
",h_coin_ev"
|
||||||
",ev_sig"
|
",ev_sig"
|
||||||
") SELECT $1, $2, $3, "
|
") SELECT $1, $2, $3, "
|
||||||
" denominations_serial, $5, $6, $7"
|
" denominations_serial, $5, $6, $7, $8"
|
||||||
" FROM denominations"
|
" FROM denominations"
|
||||||
" WHERE denom_pub_hash=$4;",
|
" WHERE denom_pub_hash=$4;",
|
||||||
7),
|
8),
|
||||||
/* Obtain information about the coins created in a refresh
|
/* Obtain information about the coins created in a refresh
|
||||||
operation, used in #postgres_get_refresh_reveal() */
|
operation, used in #postgres_get_refresh_reveal() */
|
||||||
GNUNET_PQ_make_prepare (
|
GNUNET_PQ_make_prepare (
|
||||||
@ -908,6 +909,7 @@ prepare_statements (struct PostgresClosure *pg)
|
|||||||
",rrc.h_coin_ev"
|
",rrc.h_coin_ev"
|
||||||
",rrc.link_sig"
|
",rrc.link_sig"
|
||||||
",rrc.coin_ev"
|
",rrc.coin_ev"
|
||||||
|
",rrc.ewv"
|
||||||
",rrc.ev_sig"
|
",rrc.ev_sig"
|
||||||
" FROM refresh_commitments"
|
" FROM refresh_commitments"
|
||||||
" JOIN refresh_revealed_coins rrc"
|
" JOIN refresh_revealed_coins rrc"
|
||||||
@ -1213,7 +1215,9 @@ prepare_statements (struct PostgresClosure *pg)
|
|||||||
" tp.transfer_pub"
|
" tp.transfer_pub"
|
||||||
",denoms.denom_pub"
|
",denoms.denom_pub"
|
||||||
",rrc.ev_sig"
|
",rrc.ev_sig"
|
||||||
|
",rrc.ewv"
|
||||||
",rrc.link_sig"
|
",rrc.link_sig"
|
||||||
|
",rrc.freshcoin_index"
|
||||||
" FROM refresh_commitments"
|
" FROM refresh_commitments"
|
||||||
" JOIN refresh_revealed_coins rrc"
|
" JOIN refresh_revealed_coins rrc"
|
||||||
" USING (melt_serial_id)"
|
" USING (melt_serial_id)"
|
||||||
@ -2241,6 +2245,7 @@ prepare_statements (struct PostgresClosure *pg)
|
|||||||
",link_sig"
|
",link_sig"
|
||||||
",coin_ev"
|
",coin_ev"
|
||||||
",ev_sig"
|
",ev_sig"
|
||||||
|
",ewv"
|
||||||
",denominations_serial"
|
",denominations_serial"
|
||||||
",melt_serial_id"
|
",melt_serial_id"
|
||||||
" FROM refresh_revealed_coins"
|
" FROM refresh_revealed_coins"
|
||||||
@ -2532,11 +2537,12 @@ prepare_statements (struct PostgresClosure *pg)
|
|||||||
",coin_ev"
|
",coin_ev"
|
||||||
",h_coin_ev"
|
",h_coin_ev"
|
||||||
",ev_sig"
|
",ev_sig"
|
||||||
|
",ewv"
|
||||||
",denominations_serial"
|
",denominations_serial"
|
||||||
",melt_serial_id"
|
",melt_serial_id"
|
||||||
") VALUES "
|
") VALUES "
|
||||||
"($1, $2, $3, $4, $5, $6, $7, $8);",
|
"($1, $2, $3, $4, $5, $6, $7, $8, $9);",
|
||||||
8),
|
9),
|
||||||
GNUNET_PQ_make_prepare (
|
GNUNET_PQ_make_prepare (
|
||||||
"insert_into_table_refresh_transfer_keys",
|
"insert_into_table_refresh_transfer_keys",
|
||||||
"INSERT INTO refresh_transfer_keys"
|
"INSERT INTO refresh_transfer_keys"
|
||||||
@ -6095,6 +6101,8 @@ postgres_insert_refresh_reveal (
|
|||||||
GNUNET_PQ_query_param_auto_from_type (&rrc->orig_coin_link_sig),
|
GNUNET_PQ_query_param_auto_from_type (&rrc->orig_coin_link_sig),
|
||||||
GNUNET_PQ_query_param_auto_from_type (&rrc->h_denom_pub),
|
GNUNET_PQ_query_param_auto_from_type (&rrc->h_denom_pub),
|
||||||
TALER_PQ_query_param_blinded_planchet (&rrc->blinded_planchet),
|
TALER_PQ_query_param_blinded_planchet (&rrc->blinded_planchet),
|
||||||
|
// FIXME: needed? review link protocol!
|
||||||
|
TALER_PQ_query_param_exchange_withdraw_values (&rrc->exchange_vals),
|
||||||
GNUNET_PQ_query_param_auto_from_type (&rrc->coin_envelope_hash),
|
GNUNET_PQ_query_param_auto_from_type (&rrc->coin_envelope_hash),
|
||||||
TALER_PQ_query_param_blinded_denom_sig (&rrc->coin_sig),
|
TALER_PQ_query_param_blinded_denom_sig (&rrc->coin_sig),
|
||||||
GNUNET_PQ_query_param_end
|
GNUNET_PQ_query_param_end
|
||||||
@ -6203,6 +6211,9 @@ add_revealed_coins (void *cls,
|
|||||||
&rrc->coin_envelope_hash),
|
&rrc->coin_envelope_hash),
|
||||||
TALER_PQ_result_spec_blinded_planchet ("coin_ev",
|
TALER_PQ_result_spec_blinded_planchet ("coin_ev",
|
||||||
&rrc->blinded_planchet),
|
&rrc->blinded_planchet),
|
||||||
|
// FIXME: needed? review link protocol!
|
||||||
|
TALER_PQ_result_spec_exchange_withdraw_values ("ewv",
|
||||||
|
&rrc->exchange_vals),
|
||||||
TALER_PQ_result_spec_blinded_denom_sig ("ev_sig",
|
TALER_PQ_result_spec_blinded_denom_sig ("ev_sig",
|
||||||
&rrc->coin_sig),
|
&rrc->coin_sig),
|
||||||
GNUNET_PQ_result_spec_end
|
GNUNET_PQ_result_spec_end
|
||||||
@ -6384,6 +6395,11 @@ add_ldl (void *cls,
|
|||||||
&pos->orig_coin_link_sig),
|
&pos->orig_coin_link_sig),
|
||||||
TALER_PQ_result_spec_blinded_denom_sig ("ev_sig",
|
TALER_PQ_result_spec_blinded_denom_sig ("ev_sig",
|
||||||
&pos->ev_sig),
|
&pos->ev_sig),
|
||||||
|
GNUNET_PQ_result_spec_uint32 ("freshcoin_index",
|
||||||
|
&pos->coin_refresh_offset),
|
||||||
|
// FIXME: needed? review link protocol!
|
||||||
|
TALER_PQ_result_spec_exchange_withdraw_values ("ewv",
|
||||||
|
&pos->alg_values),
|
||||||
TALER_PQ_result_spec_denom_pub ("denom_pub",
|
TALER_PQ_result_spec_denom_pub ("denom_pub",
|
||||||
&pos->denom_pub),
|
&pos->denom_pub),
|
||||||
GNUNET_PQ_result_spec_end
|
GNUNET_PQ_result_spec_end
|
||||||
|
@ -1565,6 +1565,8 @@ run (void *cls)
|
|||||||
TALER_denom_sig_unblind (&ds,
|
TALER_denom_sig_unblind (&ds,
|
||||||
&cbc2.sig,
|
&cbc2.sig,
|
||||||
&bks,
|
&bks,
|
||||||
|
&c_hash,
|
||||||
|
&alg_values,
|
||||||
&dkp->pub));
|
&dkp->pub));
|
||||||
FAILIF (GNUNET_OK !=
|
FAILIF (GNUNET_OK !=
|
||||||
TALER_denom_pub_verify (&dkp->pub,
|
TALER_denom_pub_verify (&dkp->pub,
|
||||||
@ -1582,6 +1584,8 @@ run (void *cls)
|
|||||||
TALER_denom_sig_unblind (&deposit.coin.denom_sig,
|
TALER_denom_sig_unblind (&deposit.coin.denom_sig,
|
||||||
&cbc.sig,
|
&cbc.sig,
|
||||||
&bks,
|
&bks,
|
||||||
|
&c_hash,
|
||||||
|
&alg_values,
|
||||||
&dkp->pub));
|
&dkp->pub));
|
||||||
deadline = GNUNET_TIME_timestamp_get ();
|
deadline = GNUNET_TIME_timestamp_get ();
|
||||||
{
|
{
|
||||||
@ -1760,6 +1764,7 @@ run (void *cls)
|
|||||||
rp->blinded_msg_size);
|
rp->blinded_msg_size);
|
||||||
TALER_denom_pub_hash (&new_dkp[cnt]->pub,
|
TALER_denom_pub_hash (&new_dkp[cnt]->pub,
|
||||||
&ccoin->h_denom_pub);
|
&ccoin->h_denom_pub);
|
||||||
|
ccoin->exchange_vals = alg_values;
|
||||||
TALER_coin_ev_hash (bp,
|
TALER_coin_ev_hash (bp,
|
||||||
&ccoin->h_denom_pub,
|
&ccoin->h_denom_pub,
|
||||||
&ccoin->coin_envelope_hash);
|
&ccoin->coin_envelope_hash);
|
||||||
@ -2167,6 +2172,8 @@ run (void *cls)
|
|||||||
TALER_denom_sig_unblind (&deposit.coin.denom_sig,
|
TALER_denom_sig_unblind (&deposit.coin.denom_sig,
|
||||||
&cbc.sig,
|
&cbc.sig,
|
||||||
&bks,
|
&bks,
|
||||||
|
&c_hash,
|
||||||
|
&alg_values,
|
||||||
&dkp->pub));
|
&dkp->pub));
|
||||||
RND_BLK (&deposit.csig);
|
RND_BLK (&deposit.csig);
|
||||||
RND_BLK (&deposit.merchant_pub);
|
RND_BLK (&deposit.merchant_pub);
|
||||||
|
@ -317,6 +317,7 @@ struct TALER_EXCHANGEDB_TableData
|
|||||||
uint64_t denominations_serial;
|
uint64_t denominations_serial;
|
||||||
void *coin_ev;
|
void *coin_ev;
|
||||||
size_t coin_ev_size;
|
size_t coin_ev_size;
|
||||||
|
struct TALER_ExchangeWithdrawValues ewv;
|
||||||
// h_coin_ev omitted, to be recomputed!
|
// h_coin_ev omitted, to be recomputed!
|
||||||
struct TALER_BlindedDenominationSignature ev_sig;
|
struct TALER_BlindedDenominationSignature ev_sig;
|
||||||
} refresh_revealed_coins;
|
} refresh_revealed_coins;
|
||||||
@ -1368,12 +1369,23 @@ struct TALER_EXCHANGEDB_LinkList
|
|||||||
*/
|
*/
|
||||||
struct TALER_BlindedDenominationSignature ev_sig;
|
struct TALER_BlindedDenominationSignature ev_sig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exchange-provided values during the coin generation.
|
||||||
|
*/
|
||||||
|
struct TALER_ExchangeWithdrawValues alg_values;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signature of the original coin being refreshed over the
|
* Signature of the original coin being refreshed over the
|
||||||
* link data, of type #TALER_SIGNATURE_WALLET_COIN_LINK
|
* link data, of type #TALER_SIGNATURE_WALLET_COIN_LINK
|
||||||
*/
|
*/
|
||||||
struct TALER_CoinSpendSignatureP orig_coin_link_sig;
|
struct TALER_CoinSpendSignatureP orig_coin_link_sig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Offset that generated this coin in the refresh
|
||||||
|
* operation.
|
||||||
|
*/
|
||||||
|
uint32_t coin_refresh_offset;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1645,6 +1657,12 @@ struct TALER_EXCHANGEDB_RefreshRevealedCoin
|
|||||||
*/
|
*/
|
||||||
struct TALER_BlindedDenominationSignature coin_sig;
|
struct TALER_BlindedDenominationSignature coin_sig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Values contributed from the exchange to the
|
||||||
|
* coin generation (see /csr).
|
||||||
|
*/
|
||||||
|
struct TALER_ExchangeWithdrawValues exchange_vals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Blinded message to be signed (in envelope).
|
* Blinded message to be signed (in envelope).
|
||||||
*/
|
*/
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
This file is part of TALER
|
This file is part of TALER
|
||||||
Copyright (C) 2014, 2015, 2016 Taler Systems SA
|
Copyright (C) 2014-2022 Taler Systems SA
|
||||||
|
|
||||||
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
|
||||||
@ -102,6 +102,18 @@ TALER_PQ_query_param_blinded_denom_sig (
|
|||||||
const struct TALER_BlindedDenominationSignature *denom_sig);
|
const struct TALER_BlindedDenominationSignature *denom_sig);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate query parameter for the exchange's contribution during a
|
||||||
|
* withdraw. Internally, the various attributes of the @a alg_values will be
|
||||||
|
* serialized into on variable-size BLOB.
|
||||||
|
*
|
||||||
|
* @param x pointer to the query parameter to pass
|
||||||
|
*/
|
||||||
|
struct GNUNET_PQ_QueryParam
|
||||||
|
TALER_PQ_query_param_exchange_withdraw_values (
|
||||||
|
const struct TALER_ExchangeWithdrawValues *alg_values);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate query parameter for a JSON object (stored as a string
|
* Generate query parameter for a JSON object (stored as a string
|
||||||
* in the DB). Note that @a x must really be a JSON object or array,
|
* in the DB). Note that @a x must really be a JSON object or array,
|
||||||
@ -179,6 +191,19 @@ TALER_PQ_result_spec_blinded_denom_sig (
|
|||||||
struct TALER_BlindedDenominationSignature *denom_sig);
|
struct TALER_BlindedDenominationSignature *denom_sig);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exchange withdraw values expected.
|
||||||
|
*
|
||||||
|
* @param name name of the field in the table
|
||||||
|
* @param[out] ewv where to store the exchange values
|
||||||
|
* @return array entry for the result specification to use
|
||||||
|
*/
|
||||||
|
struct GNUNET_PQ_ResultSpec
|
||||||
|
TALER_PQ_result_spec_exchange_withdraw_values (
|
||||||
|
const char *name,
|
||||||
|
struct TALER_ExchangeWithdrawValues *ewv);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Blinded planchet expected.
|
* Blinded planchet expected.
|
||||||
*
|
*
|
||||||
|
@ -95,18 +95,25 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh,
|
|||||||
struct TALER_DenominationPublicKey rpub;
|
struct TALER_DenominationPublicKey rpub;
|
||||||
struct TALER_CoinSpendSignatureP link_sig;
|
struct TALER_CoinSpendSignatureP link_sig;
|
||||||
union TALER_DenominationBlindingKeyP bks;
|
union TALER_DenominationBlindingKeyP bks;
|
||||||
|
struct TALER_ExchangeWithdrawValues alg_values;
|
||||||
|
uint32_t coin_idx;
|
||||||
struct GNUNET_JSON_Specification spec[] = {
|
struct GNUNET_JSON_Specification spec[] = {
|
||||||
TALER_JSON_spec_denom_pub ("denom_pub",
|
TALER_JSON_spec_denom_pub ("denom_pub",
|
||||||
&rpub),
|
&rpub),
|
||||||
TALER_JSON_spec_blinded_denom_sig ("ev_sig",
|
TALER_JSON_spec_blinded_denom_sig ("ev_sig",
|
||||||
&bsig),
|
&bsig),
|
||||||
|
// FIXME: add to spec!
|
||||||
|
TALER_JSON_spec_exchange_withdraw_values ("ewv",
|
||||||
|
&alg_values),
|
||||||
GNUNET_JSON_spec_fixed_auto ("link_sig",
|
GNUNET_JSON_spec_fixed_auto ("link_sig",
|
||||||
&link_sig),
|
&link_sig),
|
||||||
|
// FIXME: add to spec!
|
||||||
|
GNUNET_JSON_spec_uint32 ("coin_idx",
|
||||||
|
&coin_idx),
|
||||||
GNUNET_JSON_spec_end ()
|
GNUNET_JSON_spec_end ()
|
||||||
};
|
};
|
||||||
struct TALER_TransferSecretP secret;
|
struct TALER_TransferSecretP secret;
|
||||||
struct TALER_PlanchetSecretsP ps;
|
struct TALER_PlanchetSecretsP ps;
|
||||||
struct TALER_ExchangeWithdrawValues alg_values;
|
|
||||||
struct TALER_PlanchetDetail pd;
|
struct TALER_PlanchetDetail pd;
|
||||||
struct TALER_CoinPubHash c_hash;
|
struct TALER_CoinPubHash c_hash;
|
||||||
|
|
||||||
@ -125,9 +132,6 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh,
|
|||||||
TALER_transfer_secret_to_planchet_secret (&secret,
|
TALER_transfer_secret_to_planchet_secret (&secret,
|
||||||
coin_num,
|
coin_num,
|
||||||
&ps);
|
&ps);
|
||||||
|
|
||||||
// TODO: implement cipher handling
|
|
||||||
alg_values.cipher = TALER_DENOMINATION_RSA;
|
|
||||||
TALER_planchet_setup_coin_priv (&ps,
|
TALER_planchet_setup_coin_priv (&ps,
|
||||||
&alg_values,
|
&alg_values,
|
||||||
coin_priv);
|
coin_priv);
|
||||||
@ -165,6 +169,20 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh,
|
|||||||
|
|
||||||
GNUNET_CRYPTO_eddsa_key_get_public (&lh->coin_priv.eddsa_priv,
|
GNUNET_CRYPTO_eddsa_key_get_public (&lh->coin_priv.eddsa_priv,
|
||||||
&old_coin_pub.eddsa_pub);
|
&old_coin_pub.eddsa_pub);
|
||||||
|
// FIXME-NEXT: this is probably the wrong 'ps'!
|
||||||
|
// However, the 'right' PS is not something the
|
||||||
|
// exchange could even give us. So probably we
|
||||||
|
// really need to change the derivation structure
|
||||||
|
// during refresh to derive the nonces differently
|
||||||
|
// and make /link possible!
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||||
|
"Link using PS(%u)=%s\n",
|
||||||
|
(unsigned int) coin_idx,
|
||||||
|
TALER_B2S (&ps));
|
||||||
|
TALER_cs_refresh_nonce_derive (
|
||||||
|
&ps,
|
||||||
|
coin_idx,
|
||||||
|
&pd.blinded_planchet.details.cs_blinded_planchet.nonce);
|
||||||
TALER_coin_ev_hash (&pd.blinded_planchet,
|
TALER_coin_ev_hash (&pd.blinded_planchet,
|
||||||
&pd.denom_pub_hash,
|
&pd.denom_pub_hash,
|
||||||
&coin_envelope_hash);
|
&coin_envelope_hash);
|
||||||
|
@ -150,6 +150,10 @@ TALER_EXCHANGE_get_melt_data_ (
|
|||||||
so this computation is redundant, and here additionally
|
so this computation is redundant, and here additionally
|
||||||
repeated KAPPA times. Could be avoided with slightly
|
repeated KAPPA times. Could be avoided with slightly
|
||||||
more bookkeeping in the future */
|
more bookkeeping in the future */
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||||
|
"Refresh using PS(%u)=%s\n",
|
||||||
|
j,
|
||||||
|
TALER_B2S (&ps));
|
||||||
TALER_cs_refresh_nonce_derive (
|
TALER_cs_refresh_nonce_derive (
|
||||||
ps,
|
ps,
|
||||||
j,
|
j,
|
||||||
|
@ -527,6 +527,94 @@ TALER_PQ_query_param_blinded_planchet (
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function called to convert input argument into SQL parameters.
|
||||||
|
*
|
||||||
|
* @param cls closure
|
||||||
|
* @param data pointer to input argument
|
||||||
|
* @param data_len number of bytes in @a data (if applicable)
|
||||||
|
* @param[out] param_values SQL data to set
|
||||||
|
* @param[out] param_lengths SQL length data to set
|
||||||
|
* @param[out] param_formats SQL format data to set
|
||||||
|
* @param param_length number of entries available in the @a param_values, @a param_lengths and @a param_formats arrays
|
||||||
|
* @param[out] scratch buffer for dynamic allocations (to be done via #GNUNET_malloc()
|
||||||
|
* @param scratch_length number of entries left in @a scratch
|
||||||
|
* @return -1 on error, number of offsets used in @a scratch otherwise
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
qconv_exchange_withdraw_values (void *cls,
|
||||||
|
const void *data,
|
||||||
|
size_t data_len,
|
||||||
|
void *param_values[],
|
||||||
|
int param_lengths[],
|
||||||
|
int param_formats[],
|
||||||
|
unsigned int param_length,
|
||||||
|
void *scratch[],
|
||||||
|
unsigned int scratch_length)
|
||||||
|
{
|
||||||
|
const struct TALER_ExchangeWithdrawValues *alg_values = data;
|
||||||
|
size_t tlen;
|
||||||
|
size_t len;
|
||||||
|
uint32_t be[2];
|
||||||
|
char *buf;
|
||||||
|
|
||||||
|
(void) cls;
|
||||||
|
(void) data_len;
|
||||||
|
GNUNET_assert (1 == param_length);
|
||||||
|
GNUNET_assert (scratch_length > 0);
|
||||||
|
GNUNET_break (NULL == cls);
|
||||||
|
be[0] = htonl ((uint32_t) alg_values->cipher);
|
||||||
|
be[1] = htonl (0x010000); /* magic marker: EWV */
|
||||||
|
switch (alg_values->cipher)
|
||||||
|
{
|
||||||
|
case TALER_DENOMINATION_RSA:
|
||||||
|
tlen = 0;
|
||||||
|
break;
|
||||||
|
case TALER_DENOMINATION_CS:
|
||||||
|
tlen = sizeof (struct TALER_ExchangeWithdrawCsValues);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
GNUNET_assert (0);
|
||||||
|
}
|
||||||
|
len = tlen + sizeof (be);
|
||||||
|
buf = GNUNET_malloc (len);
|
||||||
|
memcpy (buf,
|
||||||
|
&be,
|
||||||
|
sizeof (be));
|
||||||
|
switch (alg_values->cipher)
|
||||||
|
{
|
||||||
|
case TALER_DENOMINATION_RSA:
|
||||||
|
break;
|
||||||
|
case TALER_DENOMINATION_CS:
|
||||||
|
memcpy (&buf[sizeof (be)],
|
||||||
|
&alg_values->details.cs_values,
|
||||||
|
tlen);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
GNUNET_assert (0);
|
||||||
|
}
|
||||||
|
scratch[0] = buf;
|
||||||
|
param_values[0] = (void *) buf;
|
||||||
|
param_lengths[0] = len;
|
||||||
|
param_formats[0] = 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct GNUNET_PQ_QueryParam
|
||||||
|
TALER_PQ_query_param_exchange_withdraw_values (
|
||||||
|
const struct TALER_ExchangeWithdrawValues *alg_values)
|
||||||
|
{
|
||||||
|
struct GNUNET_PQ_QueryParam res = {
|
||||||
|
.conv = &qconv_exchange_withdraw_values,
|
||||||
|
.data = alg_values,
|
||||||
|
.num_params = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function called to convert input argument into SQL parameters.
|
* Function called to convert input argument into SQL parameters.
|
||||||
*
|
*
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
This file is part of TALER
|
This file is part of TALER
|
||||||
Copyright (C) 2014, 2015, 2016, 2021 Taler Systems SA
|
Copyright (C) 2014-2022 Taler Systems SA
|
||||||
|
|
||||||
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
|
||||||
@ -855,4 +855,110 @@ TALER_PQ_result_spec_blinded_planchet (
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract data from a Postgres database @a result at row @a row.
|
||||||
|
*
|
||||||
|
* @param cls closure
|
||||||
|
* @param result where to extract data from
|
||||||
|
* @param int row to extract data from
|
||||||
|
* @param fname name (or prefix) of the fields to extract from
|
||||||
|
* @param[in,out] dst_size where to store size of result, may be NULL
|
||||||
|
* @param[out] dst where to store the result
|
||||||
|
* @return
|
||||||
|
* #GNUNET_YES if all results could be extracted
|
||||||
|
* #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
|
||||||
|
*/
|
||||||
|
static enum GNUNET_GenericReturnValue
|
||||||
|
extract_exchange_withdraw_values (void *cls,
|
||||||
|
PGresult *result,
|
||||||
|
int row,
|
||||||
|
const char *fname,
|
||||||
|
size_t *dst_size,
|
||||||
|
void *dst)
|
||||||
|
{
|
||||||
|
struct TALER_ExchangeWithdrawValues *alg_values = dst;
|
||||||
|
size_t len;
|
||||||
|
const char *res;
|
||||||
|
int fnum;
|
||||||
|
uint32_t be[2];
|
||||||
|
|
||||||
|
(void) cls;
|
||||||
|
(void) dst_size;
|
||||||
|
fnum = PQfnumber (result,
|
||||||
|
fname);
|
||||||
|
if (fnum < 0)
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
if (PQgetisnull (result,
|
||||||
|
row,
|
||||||
|
fnum))
|
||||||
|
return GNUNET_NO;
|
||||||
|
|
||||||
|
/* if a field is null, continue but
|
||||||
|
* remember that we now return a different result */
|
||||||
|
len = PQgetlength (result,
|
||||||
|
row,
|
||||||
|
fnum);
|
||||||
|
res = PQgetvalue (result,
|
||||||
|
row,
|
||||||
|
fnum);
|
||||||
|
if (len < sizeof (be))
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
memcpy (&be,
|
||||||
|
res,
|
||||||
|
sizeof (be));
|
||||||
|
if (0x010000 != ntohl (be[1])) /* magic marker: EWV */
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
res += sizeof (be);
|
||||||
|
len -= sizeof (be);
|
||||||
|
alg_values->cipher = ntohl (be[0]);
|
||||||
|
switch (alg_values->cipher)
|
||||||
|
{
|
||||||
|
case TALER_DENOMINATION_RSA:
|
||||||
|
if (0 != len)
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
return GNUNET_OK;
|
||||||
|
case TALER_DENOMINATION_CS:
|
||||||
|
if (sizeof (struct TALER_ExchangeWithdrawCsValues) != len)
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
memcpy (&alg_values->details.cs_values,
|
||||||
|
res,
|
||||||
|
len);
|
||||||
|
return GNUNET_OK;
|
||||||
|
default:
|
||||||
|
GNUNET_break (0);
|
||||||
|
}
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct GNUNET_PQ_ResultSpec
|
||||||
|
TALER_PQ_result_spec_exchange_withdraw_values (
|
||||||
|
const char *name,
|
||||||
|
struct TALER_ExchangeWithdrawValues *ewv)
|
||||||
|
{
|
||||||
|
struct GNUNET_PQ_ResultSpec res = {
|
||||||
|
.conv = &extract_exchange_withdraw_values,
|
||||||
|
.dst = (void *) ewv,
|
||||||
|
.fname = name
|
||||||
|
};
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* end of pq_result_helper.c */
|
/* end of pq_result_helper.c */
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
This file is part of TALER
|
This file is part of TALER
|
||||||
Copyright (C) 2014--2020 Taler Systems SA
|
Copyright (C) 2014--2022 Taler Systems SA
|
||||||
|
|
||||||
TALER is free software; you can redistribute it and/or modify
|
TALER is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as
|
it under the terms of the GNU General Public License as
|
||||||
@ -41,9 +41,12 @@
|
|||||||
*/
|
*/
|
||||||
static char *config_file;
|
static char *config_file;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Special configuration file to use when we want reserves
|
||||||
|
* to expire 'immediately'.
|
||||||
|
*/
|
||||||
static char *config_file_expire_reserve_now;
|
static char *config_file_expire_reserve_now;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exchange configuration data.
|
* Exchange configuration data.
|
||||||
*/
|
*/
|
||||||
@ -54,6 +57,14 @@ static struct TALER_TESTING_ExchangeConfiguration ec;
|
|||||||
*/
|
*/
|
||||||
static struct TALER_TESTING_BankConfiguration bc;
|
static struct TALER_TESTING_BankConfiguration bc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Some tests behave differently when using CS as we cannot
|
||||||
|
* re-use the coin private key for different denominations
|
||||||
|
* due to the derivation of it with the /csr values. Hence
|
||||||
|
* some tests behave differently in CS mode, hence this
|
||||||
|
* flag.
|
||||||
|
*/
|
||||||
|
static bool uses_cs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute the taler-exchange-wirewatch command with
|
* Execute the taler-exchange-wirewatch command with
|
||||||
@ -142,6 +153,11 @@ run (void *cls,
|
|||||||
/**
|
/**
|
||||||
* Withdraw EUR:1 using the SAME private coin key as for the previous coin
|
* Withdraw EUR:1 using the SAME private coin key as for the previous coin
|
||||||
* (in violation of the specification, to be detected on spending!).
|
* (in violation of the specification, to be detected on spending!).
|
||||||
|
* However, note that this does NOT work with 'CS', as for a different
|
||||||
|
* denomination we get different R0/R1 values from the exchange, and
|
||||||
|
* thus will generate a different coin private key as R0/R1 are hashed
|
||||||
|
* into the coin priv. So here, we fail to 'reuse' the key due to the
|
||||||
|
* cryptographic construction!
|
||||||
*/
|
*/
|
||||||
TALER_TESTING_cmd_withdraw_amount_reuse_key ("withdraw-coin-1x",
|
TALER_TESTING_cmd_withdraw_amount_reuse_key ("withdraw-coin-1x",
|
||||||
"create-reserve-1",
|
"create-reserve-1",
|
||||||
@ -180,6 +196,13 @@ run (void *cls,
|
|||||||
TALER_TESTING_cmd_deposit_replay ("deposit-simple-replay",
|
TALER_TESTING_cmd_deposit_replay ("deposit-simple-replay",
|
||||||
"deposit-simple",
|
"deposit-simple",
|
||||||
MHD_HTTP_OK),
|
MHD_HTTP_OK),
|
||||||
|
/* This creates a conflict, as we have the same coin public key (reuse!),
|
||||||
|
but different denomination public keys (which is not allowed).
|
||||||
|
However, note that this does NOT work with 'CS', as for a different
|
||||||
|
denomination we get different R0/R1 values from the exchange, and
|
||||||
|
thus will generate a different coin private key as R0/R1 are hashed
|
||||||
|
into the coin priv. So here, we fail to 'reuse' the key due to the
|
||||||
|
cryptographic construction! */
|
||||||
TALER_TESTING_cmd_deposit ("deposit-reused-coin-key-failure",
|
TALER_TESTING_cmd_deposit ("deposit-reused-coin-key-failure",
|
||||||
"withdraw-coin-1x",
|
"withdraw-coin-1x",
|
||||||
0,
|
0,
|
||||||
@ -187,7 +210,9 @@ run (void *cls,
|
|||||||
"{\"items\":[{\"name\":\"ice cream\",\"value\":1}]}",
|
"{\"items\":[{\"name\":\"ice cream\",\"value\":1}]}",
|
||||||
GNUNET_TIME_UNIT_ZERO,
|
GNUNET_TIME_UNIT_ZERO,
|
||||||
"EUR:1",
|
"EUR:1",
|
||||||
MHD_HTTP_CONFLICT),
|
uses_cs
|
||||||
|
? MHD_HTTP_OK
|
||||||
|
: MHD_HTTP_CONFLICT),
|
||||||
/**
|
/**
|
||||||
* Try to double spend using different wire details.
|
* Try to double spend using different wire details.
|
||||||
*/
|
*/
|
||||||
@ -230,7 +255,10 @@ run (void *cls,
|
|||||||
struct TALER_TESTING_Command refresh[] = {
|
struct TALER_TESTING_Command refresh[] = {
|
||||||
/**
|
/**
|
||||||
* Try to melt the coin that shared the private key with another
|
* Try to melt the coin that shared the private key with another
|
||||||
* coin (should fail). */
|
* coin (should fail). Note that in the CS-case, we fail also
|
||||||
|
* with MHD_HTTP_CONFLICT, but for a different reason: here it
|
||||||
|
* is not a denomination conflict, but a double-spending conflict.
|
||||||
|
*/
|
||||||
TALER_TESTING_cmd_melt ("refresh-melt-reused-coin-key-failure",
|
TALER_TESTING_cmd_melt ("refresh-melt-reused-coin-key-failure",
|
||||||
"withdraw-coin-1x",
|
"withdraw-coin-1x",
|
||||||
MHD_HTTP_CONFLICT,
|
MHD_HTTP_CONFLICT,
|
||||||
@ -839,7 +867,9 @@ run (void *cls,
|
|||||||
config_file),
|
config_file),
|
||||||
/* Check recoup is failing for the coin with the reused coin key */
|
/* Check recoup is failing for the coin with the reused coin key */
|
||||||
TALER_TESTING_cmd_recoup ("recoup-2x",
|
TALER_TESTING_cmd_recoup ("recoup-2x",
|
||||||
MHD_HTTP_CONFLICT,
|
uses_cs
|
||||||
|
? MHD_HTTP_OK
|
||||||
|
: MHD_HTTP_CONFLICT,
|
||||||
"withdraw-coin-1x",
|
"withdraw-coin-1x",
|
||||||
"EUR:1"),
|
"EUR:1"),
|
||||||
TALER_TESTING_cmd_recoup ("recoup-2",
|
TALER_TESTING_cmd_recoup ("recoup-2",
|
||||||
@ -988,6 +1018,7 @@ main (int argc,
|
|||||||
NULL);
|
NULL);
|
||||||
cipher = GNUNET_TESTING_get_testname_from_underscore (argv[0]);
|
cipher = GNUNET_TESTING_get_testname_from_underscore (argv[0]);
|
||||||
GNUNET_assert (NULL != cipher);
|
GNUNET_assert (NULL != cipher);
|
||||||
|
uses_cs = (0 == strcmp (cipher, "cs"));
|
||||||
GNUNET_asprintf (&config_file,
|
GNUNET_asprintf (&config_file,
|
||||||
"test_exchange_api-%s.conf",
|
"test_exchange_api-%s.conf",
|
||||||
cipher);
|
cipher);
|
||||||
|
@ -277,6 +277,7 @@ TALER_planchet_blinding_secret_create (
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// FIXME: move to denom.c?
|
||||||
void
|
void
|
||||||
TALER_planchet_setup_coin_priv (
|
TALER_planchet_setup_coin_priv (
|
||||||
const struct TALER_PlanchetSecretsP *ps,
|
const struct TALER_PlanchetSecretsP *ps,
|
||||||
|
Loading…
Reference in New Issue
Block a user