diff options
Diffstat (limited to 'src/exchange')
-rw-r--r-- | src/exchange/taler-exchange-httpd_deposit.c | 4 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_melt.c | 6 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_recoup-refresh.c | 7 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_recoup.c | 5 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_refreshes_reveal.c | 99 |
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); |