-fix issue with missing signature over denomination and age restriction hash in purse deposit

This commit is contained in:
Christian Grothoff 2022-06-28 20:25:45 +02:00
parent 379c580efc
commit ded7f9ca18
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
13 changed files with 240 additions and 75 deletions

View File

@ -2414,6 +2414,8 @@ purse_deposit_cb (
: TALER_ARL_exchange_url,
&deposit->purse_pub,
&deposit->amount,
&dh,
&deposit->h_age_commitment,
&deposit->coin_pub,
&deposit->coin_sig))
{

View File

@ -1289,38 +1289,15 @@ handle_purse_deposits (
struct TALER_Amount amount_minus_fee;
struct TALER_Amount new_balance;
struct ReserveSummary *rs;
struct TALER_DenominationHashP h_denom_pub;
/* should be monotonically increasing */
GNUNET_assert (rowid >= ppr.last_purse_deposits_serial_id);
ppr.last_purse_deposits_serial_id = rowid + 1;
if (GNUNET_OK !=
TALER_wallet_purse_deposit_verify (base_url,
&deposit->purse_pub,
&deposit->amount,
&deposit->coin_pub,
&deposit->coin_sig))
{
TALER_ARL_report (report_bad_sig_losses,
GNUNET_JSON_PACK (
GNUNET_JSON_pack_string ("operation",
"purse-deposit"),
GNUNET_JSON_pack_uint64 ("row",
rowid),
TALER_JSON_pack_amount ("loss",
&deposit->amount),
GNUNET_JSON_pack_data_auto ("key_pub",
&deposit->coin_pub)));
TALER_ARL_amount_add (&total_bad_sig_loss,
&total_bad_sig_loss,
&deposit->amount);
return GNUNET_OK;
}
{
const struct TALER_EXCHANGEDB_DenominationKeyInformation *issue;
enum GNUNET_DB_QueryStatus qs;
struct TALER_DenominationHashP h_denom_pub;
qs = TALER_ARL_get_denomination_info (denom_pub,
&issue,
@ -1349,6 +1326,31 @@ handle_purse_deposits (
&issue->fees.deposit);
}
if (GNUNET_OK !=
TALER_wallet_purse_deposit_verify (base_url,
&deposit->purse_pub,
&deposit->amount,
&h_denom_pub,
&deposit->h_age_commitment,
&deposit->coin_pub,
&deposit->coin_sig))
{
TALER_ARL_report (report_bad_sig_losses,
GNUNET_JSON_PACK (
GNUNET_JSON_pack_string ("operation",
"purse-deposit"),
GNUNET_JSON_pack_uint64 ("row",
rowid),
TALER_JSON_pack_amount ("loss",
&deposit->amount),
GNUNET_JSON_pack_data_auto ("key_pub",
&deposit->coin_pub)));
TALER_ARL_amount_add (&total_bad_sig_loss,
&total_bad_sig_loss,
&deposit->amount);
return GNUNET_OK;
}
TALER_ARL_amount_add (&new_balance,
auditor_balance,
&amount_minus_fee);

View File

@ -335,6 +335,8 @@ create_transaction (void *cls,
struct TALER_Amount amount;
struct TALER_CoinSpendPublicKeyP coin_pub;
struct TALER_CoinSpendSignatureP coin_sig;
struct TALER_DenominationHashP h_denom_pub;
struct TALER_AgeCommitmentHash phac;
char *partner_url = NULL;
TEH_plugin->rollback (TEH_plugin->cls);
@ -342,6 +344,8 @@ create_transaction (void *cls,
pcc->purse_pub,
&coin->cpi.coin_pub,
&amount,
&h_denom_pub,
&phac,
&coin_sig,
&partner_url);
if (qs < 0)
@ -366,6 +370,10 @@ create_transaction (void *cls,
&coin_pub),
GNUNET_JSON_pack_data_auto ("coin_sig",
&coin_sig),
GNUNET_JSON_pack_data_auto ("h_denom_pub",
&h_denom_pub),
GNUNET_JSON_pack_data_auto ("h_age_restrictions",
&phac),
GNUNET_JSON_pack_allow_null (
GNUNET_JSON_pack_string ("partner_url",
partner_url)),
@ -493,22 +501,33 @@ parse_coin (struct MHD_Connection *connection,
return res;
}
if (GNUNET_OK !=
TALER_wallet_purse_deposit_verify (TEH_base_url,
pcc->purse_pub,
&coin->amount,
&coin->cpi.coin_pub,
&coin->coin_sig))
{
TALER_LOG_WARNING (
"Invalid coin signature on /purses/$PID/create request\n");
GNUNET_JSON_parse_free (spec);
return (MHD_YES ==
TALER_MHD_reply_with_error (connection,
MHD_HTTP_FORBIDDEN,
TALER_EC_EXCHANGE_PURSE_CREATE_COIN_SIGNATURE_INVALID,
TEH_base_url))
struct TALER_AgeCommitmentHash h_age;
if (no_age_commitment)
memset (&h_age, 0, sizeof (h_age));
else
TALER_age_commitment_hash (&age_commitment,
&h_age);
if (GNUNET_OK !=
TALER_wallet_purse_deposit_verify (TEH_base_url,
pcc->purse_pub,
&coin->amount,
&coin->cpi.denom_pub_hash,
&h_age,
&coin->cpi.coin_pub,
&coin->coin_sig))
{
TALER_LOG_WARNING (
"Invalid coin signature on /purses/$PID/create request\n");
GNUNET_JSON_parse_free (spec);
return (MHD_YES ==
TALER_MHD_reply_with_error (connection,
MHD_HTTP_FORBIDDEN,
TALER_EC_EXCHANGE_PURSE_CREATE_COIN_SIGNATURE_INVALID,
TEH_base_url))
? GNUNET_NO : GNUNET_SYSERR;
}
}
/* check denomination exists and is valid */
{

View File

@ -239,6 +239,8 @@ deposit_transaction (void *cls,
struct TALER_Amount amount;
struct TALER_CoinSpendPublicKeyP coin_pub;
struct TALER_CoinSpendSignatureP coin_sig;
struct TALER_DenominationHashP h_denom_pub;
struct TALER_AgeCommitmentHash phac;
char *partner_url = NULL;
TEH_plugin->rollback (TEH_plugin->cls);
@ -246,6 +248,8 @@ deposit_transaction (void *cls,
pcc->purse_pub,
&coin->cpi.coin_pub,
&amount,
&h_denom_pub,
&phac,
&coin_sig,
&partner_url);
if (qs < 0)
@ -268,6 +272,10 @@ deposit_transaction (void *cls,
TALER_EC_EXCHANGE_PURSE_DEPOSIT_CONFLICTING_META_DATA),
GNUNET_JSON_pack_data_auto ("coin_pub",
&coin_pub),
GNUNET_JSON_pack_data_auto ("h_denom_pub",
&h_denom_pub),
GNUNET_JSON_pack_data_auto ("h_age_commitment",
&phac),
GNUNET_JSON_pack_data_auto ("coin_sig",
&coin_sig),
GNUNET_JSON_pack_allow_null (
@ -336,21 +344,33 @@ parse_coin (struct MHD_Connection *connection,
if (GNUNET_OK != res)
return res;
}
if (GNUNET_OK !=
TALER_wallet_purse_deposit_verify (TEH_base_url,
pcc->purse_pub,
&coin->amount,
&coin->cpi.coin_pub,
&coin->coin_sig))
{
TALER_LOG_WARNING ("Invalid signature on /purses/$PID/deposit request\n");
GNUNET_JSON_parse_free (spec);
return (MHD_YES ==
TALER_MHD_reply_with_error (connection,
MHD_HTTP_FORBIDDEN,
TALER_EC_EXCHANGE_PURSE_DEPOSIT_COIN_SIGNATURE_INVALID,
TEH_base_url))
struct TALER_AgeCommitmentHash h_age;
if (no_age_commitment)
memset (&h_age, 0, sizeof (h_age));
else
TALER_age_commitment_hash (&age_commitment,
&h_age);
if (GNUNET_OK !=
TALER_wallet_purse_deposit_verify (TEH_base_url,
pcc->purse_pub,
&coin->amount,
&coin->cpi.denom_pub_hash,
&h_age,
&coin->cpi.coin_pub,
&coin->coin_sig))
{
TALER_LOG_WARNING ("Invalid signature on /purses/$PID/deposit request\n");
GNUNET_JSON_parse_free (spec);
return (MHD_YES ==
TALER_MHD_reply_with_error (connection,
MHD_HTTP_FORBIDDEN,
TALER_EC_EXCHANGE_PURSE_DEPOSIT_COIN_SIGNATURE_INVALID,
TEH_base_url))
? GNUNET_NO : GNUNET_SYSERR;
}
}
/* check denomination exists and is valid */
{

View File

@ -391,6 +391,10 @@ TEH_RESPONSE_compile_transaction_history (
{
struct TALER_EXCHANGEDB_PurseDepositListEntry *pd
= pos->details.purse_deposit;
const struct TALER_AgeCommitmentHash *phac = NULL;
if (! pd->no_age_commitment)
phac = &pd->h_age_commitment;
if (0 !=
json_array_append_new (
@ -404,6 +408,9 @@ TEH_RESPONSE_compile_transaction_history (
NULL == pd->exchange_base_url
? TEH_base_url
: pd->exchange_base_url),
GNUNET_JSON_pack_allow_null (
GNUNET_JSON_pack_data_auto ("h_age_commitment",
phac)),
GNUNET_JSON_pack_data_auto ("purse_pub",
&pd->purse_pub),
GNUNET_JSON_pack_bool ("refunded",

View File

@ -1275,6 +1275,7 @@ prepare_statements (struct PostgresClosure *pg)
",denoms.fee_deposit_val"
",denoms.fee_deposit_frac"
",pd.purse_pub"
",kc.age_commitment_hash"
",pd.coin_sig"
",pd.purse_deposit_serial_id"
",pr.refunded"
@ -4199,9 +4200,13 @@ prepare_statements (struct PostgresClosure *pg)
" coin_sig"
",amount_with_fee_val"
",amount_with_fee_frac"
",denom_pub_hash"
",age_commitment_hash"
",partner_base_url"
" FROM purse_deposits"
" LEFT JOIN partners USING (partner_serial_id)"
" JOIN known_coins kc USING (coin_pub)"
" JOIN denominations USING (denominations_serial)"
" WHERE coin_pub=$2"
" AND purse_pub=$1;",
2),
@ -8571,6 +8576,8 @@ add_coin_purse_deposit (void *cls,
NULL),
GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
&deposit->coin_sig),
GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash",
&deposit->h_age_commitment),
GNUNET_PQ_result_spec_bool ("refunded",
&deposit->refunded),
GNUNET_PQ_result_spec_end
@ -8586,6 +8593,7 @@ add_coin_purse_deposit (void *cls,
chc->failed = true;
return;
}
deposit->no_age_commitment = GNUNET_is_zero (&deposit->h_age_commitment);
}
tl = GNUNET_new (struct TALER_EXCHANGEDB_TransactionList);
tl->next = chc->head;
@ -15623,6 +15631,8 @@ postgres_set_purse_balance (
* @param purse_pub purse to credit
* @param coin_pub coin to deposit (debit)
* @param[out] amount set fraction of the coin's value that was deposited (with fee)
* @param[out] h_denom_pub set to hash of denomination of the coin
* @param[out] phac set to hash of age restriction on the coin
* @param[out] coin_sig set to signature affirming the operation
* @param[out] partner_url set to the URL of the partner exchange, or NULL for ourselves, must be freed by caller
* @return transaction status code
@ -15633,6 +15643,8 @@ postgres_get_purse_deposit (
const struct TALER_PurseContractPublicKeyP *purse_pub,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
struct TALER_Amount *amount,
struct TALER_DenominationHashP *h_denom_pub,
struct TALER_AgeCommitmentHash *phac,
struct TALER_CoinSpendSignatureP *coin_sig,
char **partner_url)
{
@ -15644,6 +15656,10 @@ postgres_get_purse_deposit (
};
bool is_null;
struct GNUNET_PQ_ResultSpec rs[] = {
GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
h_denom_pub),
GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash",
phac),
GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
coin_sig),
TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",

View File

@ -2887,6 +2887,8 @@ TALER_wallet_purse_status_verify (
* @param exchange_base_url URL of the exchange hosting the purse
* @param purse_pub purses public key
* @param amount amount of the coin's value to transfer to the purse
* @param h_denom_pub hash of the coin's denomination
* @param h_age_commitment hash of the coin's age commitment
* @param coin_priv key identifying the coin to be deposited
* @param[out] coin_sig resulting signature
*/
@ -2895,6 +2897,8 @@ TALER_wallet_purse_deposit_sign (
const char *exchange_base_url,
const struct TALER_PurseContractPublicKeyP *purse_pub,
const struct TALER_Amount *amount,
const struct TALER_DenominationHashP *h_denom_pub,
const struct TALER_AgeCommitmentHash *h_age_commitment,
const struct TALER_CoinSpendPrivateKeyP *coin_priv,
struct TALER_CoinSpendSignatureP *coin_sig);
@ -2905,6 +2909,8 @@ TALER_wallet_purse_deposit_sign (
* @param exchange_base_url URL of the exchange hosting the purse
* @param purse_pub purses public key
* @param amount amount of the coin's value to transfer to the purse
* @param h_denom_pub hash of the coin's denomination
* @param h_age_commitment hash of the coin's age commitment
* @param coin_pub key identifying the coin that is being deposited
* @param[out] coin_sig resulting signature
* @return #GNUNET_OK if the signature is valid
@ -2914,6 +2920,8 @@ TALER_wallet_purse_deposit_verify (
const char *exchange_base_url,
const struct TALER_PurseContractPublicKeyP *purse_pub,
const struct TALER_Amount *amount,
const struct TALER_DenominationHashP *h_denom_pub,
const struct TALER_AgeCommitmentHash *h_age_commitment,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_CoinSpendSignatureP *coin_sig);

View File

@ -1687,20 +1687,21 @@ struct TALER_EXCHANGEDB_PurseDepositListEntry
struct TALER_CoinSpendSignatureP coin_sig;
/**
* FIXME-Oec: probably needed here, not yet used
* anywhere!
*
* Hash of the age commitment used to sign the coin, if age restriction was
* applicable to the denomination. May be all zeroes if no age restriction
* applies.
* applicable to the denomination.
*/
struct TALER_AgeCommitmentHash h_age_commitment_FIXME;
struct TALER_AgeCommitmentHash h_age_commitment;
/**
* Set to true if the coin was refunded.
*/
bool refunded;
/**
* Set to true if there was no age commitment.
*/
bool no_age_commitment;
};
@ -5349,6 +5350,8 @@ struct TALER_EXCHANGEDB_Plugin
* @param purse_pub purse to credit
* @param coin_pub coin to deposit (debit)
* @param[out] amount set fraction of the coin's value that was deposited (with fee)
* @param[out] h_denom_pub set to hash of denomination of the coin
* @param[out] phac set to hash of age restriction on the coin
* @param[out] coin_sig set to signature affirming the operation
* @param[out] partner_url set to the URL of the partner exchange, or NULL for ourselves, must be freed by caller
* @return transaction status code
@ -5359,6 +5362,8 @@ struct TALER_EXCHANGEDB_Plugin
const struct TALER_PurseContractPublicKeyP *purse_pub,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
struct TALER_Amount *amount,
struct TALER_DenominationHashP *h_denom_pub,
struct TALER_AgeCommitmentHash *phac,
struct TALER_CoinSpendSignatureP *coin_sig,
char **partner_url);

View File

@ -1170,13 +1170,22 @@ help_purse_deposit (struct CoinHistoryParseContext *pc,
struct TALER_CoinSpendSignatureP coin_sig;
const char *exchange_base_url;
bool refunded;
struct TALER_AgeCommitmentHash phac = { 0 };
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_fixed_auto ("purse_pub",
&purse_pub),
GNUNET_JSON_spec_fixed_auto ("coin_sig",
&coin_sig),
GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_fixed_auto ("h_age_commitment",
&coin_sig),
NULL),
GNUNET_JSON_spec_string ("exchange_base_url",
&exchange_base_url),
GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_fixed_auto ("h_age_commitment",
&phac),
NULL),
GNUNET_JSON_spec_bool ("refunded",
&refunded),
GNUNET_JSON_spec_end ()
@ -1195,6 +1204,8 @@ help_purse_deposit (struct CoinHistoryParseContext *pc,
exchange_base_url,
&purse_pub,
amount,
&pc->dk->h_key,
&phac,
pc->coin_pub,
&coin_sig))
{
@ -1560,12 +1571,18 @@ TALER_EXCHANGE_check_purse_coin_conflict_ (
const struct TALER_PurseContractPublicKeyP *purse_pub,
const char *exchange_url,
const json_t *proof,
struct TALER_DenominationHashP *h_denom_pub,
struct TALER_AgeCommitmentHash *phac,
struct TALER_CoinSpendPublicKeyP *coin_pub,
struct TALER_CoinSpendSignatureP *coin_sig)
{
const char *partner_url = NULL;
struct TALER_Amount amount;
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_fixed_auto ("h_denom_pub",
h_denom_pub),
GNUNET_JSON_spec_fixed_auto ("h_age_commitment",
phac),
GNUNET_JSON_spec_fixed_auto ("coin_sig",
coin_sig),
GNUNET_JSON_spec_fixed_auto ("coin_pub",
@ -1594,6 +1611,8 @@ TALER_EXCHANGE_check_purse_coin_conflict_ (
partner_url,
purse_pub,
&amount,
h_denom_pub,
phac,
coin_pub,
coin_sig))
{

View File

@ -75,6 +75,8 @@ TALER_EXCHANGE_check_purse_merge_conflict_ (
* @param purse_pub the public key of the purse
* @param exchange_url base URL of our exchange
* @param proof the proof to check
* @param[out] h_denom_pub hash of the coin's denomination
* @param[out] phac age commitment hash of the coin
* @param[out] coin_pub set to the conflicting coin
* @param[out] coin_sig set to the conflicting signature
* @return #GNUNET_OK if the @a proof is OK for @a purse_pub and showing that @a coin_pub was spent using @a coin_sig.
@ -84,6 +86,8 @@ TALER_EXCHANGE_check_purse_coin_conflict_ (
const struct TALER_PurseContractPublicKeyP *purse_pub,
const char *exchange_url,
const json_t *proof,
struct TALER_DenominationHashP *h_denom_pub,
struct TALER_AgeCommitmentHash *phac,
struct TALER_CoinSpendPublicKeyP *coin_pub,
struct TALER_CoinSpendSignatureP *coin_sig);

View File

@ -54,6 +54,11 @@ struct Deposit
*/
struct TALER_DenominationHashP h_denom_pub;
/**
* Age restriction hash for the coin.
*/
struct TALER_AgeCommitmentHash ahac;
/**
* How much did we say the coin contributed.
*/
@ -375,6 +380,8 @@ handle_purse_create_deposit_finished (void *cls,
{
struct TALER_CoinSpendPublicKeyP coin_pub;
struct TALER_CoinSpendSignatureP coin_sig;
struct TALER_DenominationHashP h_denom_pub;
struct TALER_AgeCommitmentHash phac;
bool found = false;
if (GNUNET_OK !=
@ -382,6 +389,8 @@ handle_purse_create_deposit_finished (void *cls,
&pch->purse_pub,
pch->exchange->url,
j,
&h_denom_pub,
&phac,
&coin_pub,
&coin_sig))
{
@ -398,6 +407,20 @@ handle_purse_create_deposit_finished (void *cls,
GNUNET_memcmp (&coin_pub,
&deposit->coin_pub))
continue;
if (0 !=
GNUNET_memcmp (&deposit->h_denom_pub,
&h_denom_pub))
{
found = true;
break;
}
if (0 !=
GNUNET_memcmp (&deposit->ahac,
&phac))
{
found = true;
break;
}
if (0 ==
GNUNET_memcmp (&coin_sig,
&deposit->coin_sig))
@ -571,7 +594,6 @@ TALER_EXCHANGE_purse_create_with_deposit (
const struct TALER_AgeCommitmentProof *acp = deposit->age_commitment_proof;
struct Deposit *d = &pch->deposits[i];
json_t *jdeposit;
struct TALER_AgeCommitmentHash agh;
struct TALER_AgeCommitmentHash *aghp = NULL;
struct TALER_AgeAttestation attest;
struct TALER_AgeAttestation *attestp = NULL;
@ -579,8 +601,8 @@ TALER_EXCHANGE_purse_create_with_deposit (
if (NULL != acp)
{
TALER_age_commitment_hash (&acp->commitment,
&agh);
aghp = &agh;
&d->ahac);
aghp = &d->ahac;
if (GNUNET_OK !=
TALER_age_commitment_attest (acp,
min_age,
@ -601,6 +623,8 @@ TALER_EXCHANGE_purse_create_with_deposit (
url,
&pch->purse_pub,
&deposit->amount,
&d->h_denom_pub,
&d->ahac,
&deposit->coin_priv,
&d->coin_sig);
jdeposit = GNUNET_JSON_PACK (

View File

@ -54,6 +54,11 @@ struct Coin
*/
struct TALER_DenominationHashP h_denom_pub;
/**
* Age restriction hash for the coin.
*/
struct TALER_AgeCommitmentHash ahac;
/**
* How much did we say the coin contributed.
*/
@ -234,6 +239,8 @@ handle_purse_deposit_finished (void *cls,
{
struct TALER_CoinSpendPublicKeyP coin_pub;
struct TALER_CoinSpendSignatureP coin_sig;
struct TALER_DenominationHashP h_denom_pub;
struct TALER_AgeCommitmentHash phac;
bool found = false;
if (GNUNET_OK !=
@ -241,6 +248,8 @@ handle_purse_deposit_finished (void *cls,
&pch->purse_pub,
pch->base_url,
j,
&h_denom_pub,
&phac,
&coin_pub,
&coin_sig))
{
@ -251,18 +260,32 @@ handle_purse_deposit_finished (void *cls,
}
for (unsigned int i = 0; i<pch->num_deposits; i++)
{
if (0 == GNUNET_memcmp (&coin_pub,
&pch->coins[i].coin_pub))
struct Coin *coin = &pch->coins[i];
if (0 != GNUNET_memcmp (&coin_pub,
&coin->coin_pub))
continue;
if (0 !=
GNUNET_memcmp (&coin->h_denom_pub,
&h_denom_pub))
{
if (0 == GNUNET_memcmp (&coin_sig,
&pch->coins[i].coin_sig))
{
/* identical signature => not a conflict */
continue;
}
found = true;
break;
}
if (0 !=
GNUNET_memcmp (&coin->ahac,
&phac))
{
found = true;
break;
}
if (0 == GNUNET_memcmp (&coin_sig,
&coin->coin_sig))
{
/* identical signature => not a conflict */
continue;
}
found = true;
break;
}
if (! found)
{
@ -488,7 +511,6 @@ TALER_EXCHANGE_purse_deposit (
const struct TALER_AgeCommitmentProof *acp = deposit->age_commitment_proof;
struct Coin *coin = &pch->coins[i];
json_t *jdeposit;
struct TALER_AgeCommitmentHash ach;
struct TALER_AgeCommitmentHash *achp = NULL;
struct TALER_AgeAttestation attest;
struct TALER_AgeAttestation *attestp = NULL;
@ -496,8 +518,8 @@ TALER_EXCHANGE_purse_deposit (
if (NULL != acp)
{
TALER_age_commitment_hash (&acp->commitment,
&ach);
achp = &ach;
&coin->ahac);
achp = &coin->ahac;
if (GNUNET_OK !=
TALER_age_commitment_attest (acp,
min_age,
@ -520,6 +542,8 @@ TALER_EXCHANGE_purse_deposit (
pch->base_url,
&pch->purse_pub,
&deposit->amount,
&coin->h_denom_pub,
&coin->ahac,
&deposit->coin_priv,
&coin->coin_sig);
jdeposit = GNUNET_JSON_PACK (

View File

@ -898,9 +898,16 @@ struct TALER_PurseDepositPS
*/
struct TALER_AmountNBO coin_amount;
// FIXME-CG: also sign over age commitment hash AND
// denomination hash, needed for proper known-coin
// conflict proofs!
/**
* Hash over the denomination public key used to sign the coin.
*/
struct TALER_DenominationHashP h_denom_pub GNUNET_PACKED;
/**
* Hash over the age commitment that went into the coin. Maybe all zero, if
* age commitment isn't applicable to the denomination.
*/
struct TALER_AgeCommitmentHash h_age_commitment GNUNET_PACKED;
/**
* Purse to deposit funds into.
@ -911,7 +918,7 @@ struct TALER_PurseDepositPS
* Hash of the base URL of the exchange hosting the
* @e purse_pub.
*/
struct GNUNET_HashCode h_exchange_base_url;
struct GNUNET_HashCode h_exchange_base_url GNUNET_PACKED;
};
@ -920,6 +927,8 @@ TALER_wallet_purse_deposit_sign (
const char *exchange_base_url,
const struct TALER_PurseContractPublicKeyP *purse_pub,
const struct TALER_Amount *amount,
const struct TALER_DenominationHashP *h_denom_pub,
const struct TALER_AgeCommitmentHash *h_age_commitment,
const struct TALER_CoinSpendPrivateKeyP *coin_priv,
struct TALER_CoinSpendSignatureP *coin_sig)
{
@ -927,6 +936,8 @@ TALER_wallet_purse_deposit_sign (
.purpose.size = htonl (sizeof (pm)),
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_DEPOSIT),
.purse_pub = *purse_pub,
.h_denom_pub = *h_denom_pub,
.h_age_commitment = *h_age_commitment
};
GNUNET_CRYPTO_hash (exchange_base_url,
@ -945,6 +956,8 @@ TALER_wallet_purse_deposit_verify (
const char *exchange_base_url,
const struct TALER_PurseContractPublicKeyP *purse_pub,
const struct TALER_Amount *amount,
const struct TALER_DenominationHashP *h_denom_pub,
const struct TALER_AgeCommitmentHash *h_age_commitment,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_CoinSpendSignatureP *coin_sig)
{
@ -952,6 +965,8 @@ TALER_wallet_purse_deposit_verify (
.purpose.size = htonl (sizeof (pm)),
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_DEPOSIT),
.purse_pub = *purse_pub,
.h_denom_pub = *h_denom_pub,
.h_age_commitment = *h_age_commitment
};
GNUNET_CRYPTO_hash (exchange_base_url,