summaryrefslogtreecommitdiff
path: root/src/exchange
diff options
context:
space:
mode:
Diffstat (limited to 'src/exchange')
-rw-r--r--src/exchange/taler-exchange-httpd_deposit.c4
-rw-r--r--src/exchange/taler-exchange-httpd_melt.c6
-rw-r--r--src/exchange/taler-exchange-httpd_recoup-refresh.c7
-rw-r--r--src/exchange/taler-exchange-httpd_recoup.c5
-rw-r--r--src/exchange/taler-exchange-httpd_refreshes_reveal.c99
5 files changed, 111 insertions, 10 deletions
diff --git a/src/exchange/taler-exchange-httpd_deposit.c b/src/exchange/taler-exchange-httpd_deposit.c
index d750ec70e..11a53ceaa 100644
--- a/src/exchange/taler-exchange-httpd_deposit.c
+++ b/src/exchange/taler-exchange-httpd_deposit.c
@@ -242,7 +242,7 @@ TEH_handler_deposit (struct MHD_Connection *connection,
&deposit.h_contract_terms),
GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_fixed_auto ("h_age_commitment",
- &deposit.coin.age_commitment_hash)),
+ &deposit.coin.h_age_commitment)),
GNUNET_JSON_spec_fixed_auto ("coin_sig",
&deposit.csig),
GNUNET_JSON_spec_timestamp ("timestamp",
@@ -400,7 +400,7 @@ TEH_handler_deposit (struct MHD_Connection *connection,
&deposit.deposit_fee,
&h_wire,
&deposit.h_contract_terms,
- &deposit.coin.age_commitment_hash,
+ &deposit.coin.h_age_commitment,
NULL /* h_extensions! */,
&deposit.coin.denom_pub_hash,
deposit.timestamp,
diff --git a/src/exchange/taler-exchange-httpd_melt.c b/src/exchange/taler-exchange-httpd_melt.c
index 8bfdf8cef..769b13e4d 100644
--- a/src/exchange/taler-exchange-httpd_melt.c
+++ b/src/exchange/taler-exchange-httpd_melt.c
@@ -336,7 +336,7 @@ check_melt_valid (struct MHD_Connection *connection,
&rmc->coin_refresh_fee,
&rmc->refresh_session.rc,
&rmc->refresh_session.coin.denom_pub_hash,
- &rmc->refresh_session.coin.age_commitment_hash,
+ &rmc->refresh_session.coin.h_age_commitment,
&rmc->refresh_session.coin.coin_pub,
&rmc->refresh_session.coin_sig))
{
@@ -413,8 +413,8 @@ TEH_handler_melt (struct MHD_Connection *connection,
GNUNET_JSON_spec_fixed_auto ("denom_pub_hash",
&rmc.refresh_session.coin.denom_pub_hash),
GNUNET_JSON_spec_mark_optional (
- GNUNET_JSON_spec_fixed_auto ("age_commitment_hash",
- &rmc.refresh_session.coin.age_commitment_hash)),
+ GNUNET_JSON_spec_fixed_auto ("h_age_commitment",
+ &rmc.refresh_session.coin.h_age_commitment)),
GNUNET_JSON_spec_fixed_auto ("confirm_sig",
&rmc.refresh_session.coin_sig),
TALER_JSON_spec_amount ("value_with_fee",
diff --git a/src/exchange/taler-exchange-httpd_recoup-refresh.c b/src/exchange/taler-exchange-httpd_recoup-refresh.c
index bbf6defee..4326dfe4b 100644
--- a/src/exchange/taler-exchange-httpd_recoup-refresh.c
+++ b/src/exchange/taler-exchange-httpd_recoup-refresh.c
@@ -251,7 +251,7 @@ verify_and_execute_recoup_refresh (
if (GNUNET_OK !=
TALER_denom_blind (&dk->denom_pub,
coin_bks,
- NULL, /* FIXME-Oec: TALER_AgeCommitmentHash * */
+ &coin->h_age_commitment,
&coin->coin_pub,
exchange_vals,
&c_hash,
@@ -360,7 +360,7 @@ TEH_handler_recoup_refresh (struct MHD_Connection *connection,
const json_t *root)
{
enum GNUNET_GenericReturnValue ret;
- struct TALER_CoinPublicInfo coin;
+ struct TALER_CoinPublicInfo coin = {0};
union TALER_DenominationBlindingKeyP coin_bks;
struct TALER_CoinSpendSignatureP coin_sig;
struct TALER_ExchangeWithdrawValues exchange_vals;
@@ -377,6 +377,9 @@ TEH_handler_recoup_refresh (struct MHD_Connection *connection,
GNUNET_JSON_spec_fixed_auto ("coin_sig",
&coin_sig),
GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_fixed_auto ("h_age_commitment",
+ &coin.h_age_commitment)),
+ GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_fixed_auto ("cs_nonce",
&nonce)),
GNUNET_JSON_spec_end ()
diff --git a/src/exchange/taler-exchange-httpd_recoup.c b/src/exchange/taler-exchange-httpd_recoup.c
index 4ac997e9c..00753251b 100644
--- a/src/exchange/taler-exchange-httpd_recoup.c
+++ b/src/exchange/taler-exchange-httpd_recoup.c
@@ -256,7 +256,7 @@ verify_and_execute_recoup (
if (GNUNET_OK !=
TALER_denom_blind (&dk->denom_pub,
coin_bks,
- NULL, /* FIXME-Oec: TALER_AgeCommitmentHash * */
+ &coin->h_age_commitment,
&coin->coin_pub,
exchange_vals,
&c_hash,
@@ -390,6 +390,9 @@ TEH_handler_recoup (struct MHD_Connection *connection,
GNUNET_JSON_spec_fixed_auto ("coin_sig",
&coin_sig),
GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_fixed_auto ("h_age_commitment",
+ &coin.h_age_commitment)),
+ GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_fixed_auto ("cs_nonce",
&nonce)),
GNUNET_JSON_spec_end ()
diff --git a/src/exchange/taler-exchange-httpd_refreshes_reveal.c b/src/exchange/taler-exchange-httpd_refreshes_reveal.c
index 1f0782aaa..32195f8db 100644
--- a/src/exchange/taler-exchange-httpd_refreshes_reveal.c
+++ b/src/exchange/taler-exchange-httpd_refreshes_reveal.c
@@ -103,6 +103,12 @@ struct RevealContext
const struct TEH_DenominationKey **dks;
/**
+ * Age commitment that was used for the original coin. If not NULL, its hash
+ * should be the same as melt.session.h_age_commitment.
+ */
+ struct TALER_AgeCommitment *old_age_commitment;
+
+ /**
* Array of information about fresh coins being revealed.
*/
/* FIXME: const would be nicer here, but we initalize
@@ -263,6 +269,7 @@ check_commitment (struct RevealContext *rctx,
const struct TALER_ExchangeWithdrawValues *alg_value
= &rctx->rrcs[j].exchange_vals;
struct TALER_PlanchetDetail pd;
+ struct TALER_AgeCommitmentHash *hac = NULL;
struct TALER_CoinPubHash c_hash;
struct TALER_PlanchetMasterSecretP ps;
@@ -276,12 +283,30 @@ check_commitment (struct RevealContext *rctx,
TALER_planchet_blinding_secret_create (&ps,
alg_value,
&bks);
+ /* Calculate, if applicable, the age commitment and its hash, from
+ * the transfer_secret and the old age commitment. */
+ if (NULL != rctx->old_age_commitment)
+ {
+ struct TALER_AgeCommitment ac = {0};
+ struct TALER_AgeCommitmentHash h = {0};
+
+ GNUNET_assert (GNUNET_OK ==
+ TALER_age_commitment_derive (
+ rctx->old_age_commitment,
+ ts.key.bits[0],
+ &ac));
+
+ TALER_age_commitment_hash (&ac, &h);
+
+ hac = &h;
+ }
+
GNUNET_assert (GNUNET_OK ==
TALER_planchet_prepare (rcd->dk,
alg_value,
&bks,
&coin_priv,
- NULL, /* FIXME-Oec, struct TALER_AgeCommitmentHash * */
+ hac,
&c_hash,
&pd));
if (TALER_DENOMINATION_CS == dk->cipher)
@@ -542,6 +567,77 @@ resolve_refreshes_reveal_denominations (struct MHD_Connection *connection,
}
}
+ if (TEH_age_restriction_enabled &&
+ ((NULL == old_age_commitment_json) !=
+ TALER_AgeCommitmentHash_isNullOrZero (
+ &rctx->melt.session.h_age_commitment)))
+ {
+ GNUNET_break (0);
+ return MHD_NO;
+ }
+
+ /* Reconstruct the old age commitment and verify its hash matches the one
+ * from the melt request */
+ if (TEH_age_restriction_enabled &&
+ (NULL != old_age_commitment_json))
+ {
+ enum GNUNET_GenericReturnValue res;
+ struct TALER_AgeCommitment *oac = rctx->old_age_commitment;
+ size_t ng = json_array_size (old_age_commitment_json);
+ bool failed = true;
+
+ /* Has been checked in handle_refreshes_reveal_json() */
+ GNUNET_assert (ng ==
+ TALER_extensions_age_restriction_num_groups ());
+
+ oac = GNUNET_new (struct TALER_AgeCommitment);
+ oac->mask = TEH_age_mask;
+ oac->num_pub = ng;
+ oac->num_priv = 0; /* no private keys are needed for the reveal phase */
+ oac->pub = GNUNET_new_array (ng, struct TALER_AgeCommitmentPublicKeyP);
+
+ /* Extract old age commitment */
+ for (unsigned int i = 0; i< ng; i++)
+ {
+ struct GNUNET_JSON_Specification ac_spec[] = {
+ GNUNET_JSON_spec_fixed_auto (NULL,
+ &oac->pub[i]),
+ GNUNET_JSON_spec_end ()
+ };
+
+ res = TALER_MHD_parse_json_array (connection,
+ old_age_commitment_json,
+ ac_spec,
+ i,
+ -1);
+ GNUNET_break (GNUNET_OK != res);
+ if (GNUNET_OK != res)
+ goto clean_age;
+ }
+
+ /* Sanity check: Compare hash from melting with hash of this age commitment */
+ {
+ struct TALER_AgeCommitmentHash hac = {0};
+ TALER_age_commitment_hash (oac, &hac);
+ if (0 != memcmp (&hac,
+ &rctx->melt.session.h_age_commitment,
+ sizeof(struct TALER_AgeCommitmentHash)))
+ {
+ GNUNET_break (0);
+ goto clean_age;
+ }
+ }
+
+ failed = false;
+
+clean_age:
+ if (failed)
+ {
+ TALER_age_commitment_free (oac);
+ return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
+ }
+ }
+
/* Parse link signatures array */
for (unsigned int i = 0; i<num_fresh_coins; i++)
{
@@ -567,7 +663,6 @@ resolve_refreshes_reveal_denominations (struct MHD_Connection *connection,
&rctx->gamma_tp,
&rrcs[i].coin_envelope_hash,
&rctx->melt.session.coin.coin_pub,
- NULL, // TODO-oec: calculate the correct h_age_commitment
&rrcs[i].orig_coin_link_sig))
{
GNUNET_break_op (0);