summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/auditor/taler-helper-auditor-coins.c2
-rw-r--r--src/auditor/taler-helper-auditor-reserves.c50
-rw-r--r--src/exchange/taler-exchange-httpd_purses_create.c47
-rw-r--r--src/exchange/taler-exchange-httpd_purses_deposit.c46
-rw-r--r--src/exchange/taler-exchange-httpd_responses.c7
-rw-r--r--src/exchangedb/plugin_exchangedb_postgres.c16
-rw-r--r--src/include/taler_crypto_lib.h8
-rw-r--r--src/include/taler_exchangedb_plugin.h17
-rw-r--r--src/lib/exchange_api_common.c19
-rw-r--r--src/lib/exchange_api_common.h4
-rw-r--r--src/lib/exchange_api_purse_create_with_deposit.c30
-rw-r--r--src/lib/exchange_api_purse_deposit.c46
-rw-r--r--src/util/wallet_signatures.c23
13 files changed, 240 insertions, 75 deletions
diff --git a/src/auditor/taler-helper-auditor-coins.c b/src/auditor/taler-helper-auditor-coins.c
index 56afdeb90..6940369f9 100644
--- a/src/auditor/taler-helper-auditor-coins.c
+++ b/src/auditor/taler-helper-auditor-coins.c
@@ -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))
{
diff --git a/src/auditor/taler-helper-auditor-reserves.c b/src/auditor/taler-helper-auditor-reserves.c
index f0c92c260..54d3db7c3 100644
--- a/src/auditor/taler-helper-auditor-reserves.c
+++ b/src/auditor/taler-helper-auditor-reserves.c
@@ -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);
diff --git a/src/exchange/taler-exchange-httpd_purses_create.c b/src/exchange/taler-exchange-httpd_purses_create.c
index 2c8032342..b016aeee4 100644
--- a/src/exchange/taler-exchange-httpd_purses_create.c
+++ b/src/exchange/taler-exchange-httpd_purses_create.c
@@ -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 */
{
diff --git a/src/exchange/taler-exchange-httpd_purses_deposit.c b/src/exchange/taler-exchange-httpd_purses_deposit.c
index af7200f12..4158b2936 100644
--- a/src/exchange/taler-exchange-httpd_purses_deposit.c
+++ b/src/exchange/taler-exchange-httpd_purses_deposit.c
@@ -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 */
{
diff --git a/src/exchange/taler-exchange-httpd_responses.c b/src/exchange/taler-exchange-httpd_responses.c
index 429647e16..92c585b4d 100644
--- a/src/exchange/taler-exchange-httpd_responses.c
+++ b/src/exchange/taler-exchange-httpd_responses.c
@@ -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",
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c
index d3bbb4d6a..5985fa95d 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -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",
diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h
index 274a18deb..fa13a29ca 100644
--- a/src/include/taler_crypto_lib.h
+++ b/src/include/taler_crypto_lib.h
@@ -2887,6 +2887,8 @@ TALER_wallet_purse_status_verify (
* @param exchange_base_url URL of the exchange hosting the purse
* @param purse_pub purse’s 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 purse’s 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);
diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h
index 42a6795f9..4ec2b6c78 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -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);
diff --git a/src/lib/exchange_api_common.c b/src/lib/exchange_api_common.c
index 4b36aa932..26ddb3c06 100644
--- a/src/lib/exchange_api_common.c
+++ b/src/lib/exchange_api_common.c
@@ -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))
{
diff --git a/src/lib/exchange_api_common.h b/src/lib/exchange_api_common.h
index 5721b376c..f4737ca98 100644
--- a/src/lib/exchange_api_common.h
+++ b/src/lib/exchange_api_common.h
@@ -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);
diff --git a/src/lib/exchange_api_purse_create_with_deposit.c b/src/lib/exchange_api_purse_create_with_deposit.c
index fa1de60b3..3a5b7df59 100644
--- a/src/lib/exchange_api_purse_create_with_deposit.c
+++ b/src/lib/exchange_api_purse_create_with_deposit.c
@@ -55,6 +55,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.
*/
struct TALER_Amount contribution;
@@ -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 (
diff --git a/src/lib/exchange_api_purse_deposit.c b/src/lib/exchange_api_purse_deposit.c
index 836183bbe..922251012 100644
--- a/src/lib/exchange_api_purse_deposit.c
+++ b/src/lib/exchange_api_purse_deposit.c
@@ -55,6 +55,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.
*/
struct TALER_Amount contribution;
@@ -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))
+ {
+ found = true;
+ break;
+ }
+ if (0 !=
+ GNUNET_memcmp (&coin->ahac,
+ &phac))
{
- 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_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 (
diff --git a/src/util/wallet_signatures.c b/src/util/wallet_signatures.c
index 1b8015628..f4efb2719 100644
--- a/src/util/wallet_signatures.c
+++ b/src/util/wallet_signatures.c
@@ -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,