summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/auditor/taler-helper-auditor-coins.c5
-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
-rw-r--r--src/exchangedb/plugin_exchangedb_postgres.c6
-rw-r--r--src/include/taler_crypto_lib.h22
-rw-r--r--src/include/taler_exchange_service.h13
-rw-r--r--src/lib/exchange_api_deposit.c4
-rw-r--r--src/lib/exchange_api_link.c45
-rw-r--r--src/lib/exchange_api_management_get_keys.c2
-rw-r--r--src/lib/exchange_api_refresh_common.c42
-rw-r--r--src/lib/exchange_api_refresh_common.h5
-rw-r--r--src/lib/exchange_api_refreshes_reveal.c19
-rw-r--r--src/testing/test_exchange_api_twisted.c3
-rw-r--r--src/testing/testing_api_cmd_insert_deposit.c2
-rw-r--r--src/testing/testing_api_cmd_refresh.c36
-rw-r--r--src/util/crypto.c6
-rw-r--r--src/util/wallet_signatures.c5
20 files changed, 259 insertions, 77 deletions
diff --git a/src/auditor/taler-helper-auditor-coins.c b/src/auditor/taler-helper-auditor-coins.c
index 2ed8e5a15..531f5bb46 100644
--- a/src/auditor/taler-helper-auditor-coins.c
+++ b/src/auditor/taler-helper-auditor-coins.c
@@ -1614,7 +1614,6 @@ deposit_cb (void *cls,
struct TALER_MerchantWireHash h_wire;
struct TALER_DenominationHash h_denom_pub;
struct TALER_Amount deposit_fee;
- struct TALER_AgeCommitmentHash *h_age_commitment = NULL; /* FIXME-oec */
TALER_denom_pub_hash (denom_pub,
&h_denom_pub);
@@ -1631,8 +1630,8 @@ deposit_cb (void *cls,
&deposit_fee,
&h_wire,
&deposit->h_contract_terms,
- h_age_commitment, /* FIXME-oec */
- NULL /* h_extensions! */,
+ &deposit->coin.h_age_commitment,
+ NULL /* FIXME: h_extensions! */,
&h_denom_pub,
deposit->timestamp,
&deposit->merchant_pub,
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);
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c
index 878c36f96..8f7a09404 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -5664,7 +5664,7 @@ postgres_get_known_coin (void *cls,
GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
&coin_info->denom_pub_hash),
GNUNET_PQ_result_spec_auto_from_type ("age_hash",
- &coin_info->age_commitment_hash),
+ &coin_info->h_age_commitment),
TALER_PQ_result_spec_denom_sig ("denom_sig",
&coin_info->denom_sig),
GNUNET_PQ_result_spec_end
@@ -5780,7 +5780,7 @@ postgres_ensure_coin_known (void *cls,
struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_auto_from_type (&coin->coin_pub),
GNUNET_PQ_query_param_auto_from_type (&coin->denom_pub_hash),
- GNUNET_PQ_query_param_auto_from_type (&coin->age_commitment_hash),
+ GNUNET_PQ_query_param_auto_from_type (&coin->h_age_commitment),
TALER_PQ_query_param_denom_sig (&coin->denom_sig),
GNUNET_PQ_query_param_end
};
@@ -5830,7 +5830,7 @@ postgres_ensure_coin_known (void *cls,
if ( (! is_age_hash_null) &&
(0 != GNUNET_memcmp (age_hash,
- &coin->age_commitment_hash)) )
+ &coin->h_age_commitment)) )
{
GNUNET_break (GNUNET_is_zero (age_hash));
GNUNET_break_op (0);
diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h
index 9bbf29de4..6aabf983a 100644
--- a/src/include/taler_crypto_lib.h
+++ b/src/include/taler_crypto_lib.h
@@ -979,7 +979,7 @@ struct TALER_CoinPublicInfo
* Hash of the age commitment. If no age commitment was provided, it must be
* set to all zeroes.
*/
- struct TALER_AgeCommitmentHash age_commitment_hash;
+ struct TALER_AgeCommitmentHash h_age_commitment;
/**
* (Unblinded) signature over @e coin_pub with @e denom_pub,
@@ -2351,11 +2351,12 @@ TALER_wallet_melt_verify (
* @param[out] coin_sig resulting signature
*/
void
-TALER_wallet_link_sign (const struct TALER_DenominationHash *h_denom_pub,
- const struct TALER_TransferPublicKeyP *transfer_pub,
- const struct TALER_BlindedCoinHash *bch,
- const struct TALER_CoinSpendPrivateKeyP *old_coin_priv,
- struct TALER_CoinSpendSignatureP *coin_sig);
+TALER_wallet_link_sign (
+ const struct TALER_DenominationHash *h_denom_pub,
+ const struct TALER_TransferPublicKeyP *transfer_pub,
+ const struct TALER_BlindedCoinHash *bch,
+ const struct TALER_CoinSpendPrivateKeyP *old_coin_priv,
+ struct TALER_CoinSpendSignatureP *coin_sig);
/**
@@ -2365,7 +2366,6 @@ TALER_wallet_link_sign (const struct TALER_DenominationHash *h_denom_pub,
* @param transfer_pub transfer public key
* @param h_coin_ev hash of the coin envelope
* @param old_coin_pub old coin key that the link signature is for
- * @param h_age_commitment hash of age commitment. Maybe NULL, if not applicable.
* @param coin_sig resulting signature
* @return #GNUNET_OK if the signature is valid
*/
@@ -2375,7 +2375,6 @@ TALER_wallet_link_verify (
const struct TALER_TransferPublicKeyP *transfer_pub,
const struct TALER_BlindedCoinHash *h_coin_ev,
const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
- const struct TALER_AgeCommitmentHash *h_age_commitment,
const struct TALER_CoinSpendSignatureP *coin_sig);
@@ -3283,12 +3282,11 @@ TALER_age_commitment_derive (
struct TALER_AgeCommitment *derived);
/*
- * @brief helper function to free memory inside a struct TALER_AgeCommitment
- * @param cmt the commitment from which internal memory should be freed. Note
- * that cmt itself is NOT freed!
+ * @brief helper function to free memory of a struct TALER_AgeCommitment
+ * @param cmt the commitment from which all memory should be freed.
*/
void
-TALER_age_restriction_commitment_free_inside (
+TALER_age_commitment_free (
struct TALER_AgeCommitment *cmt);
#endif
diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h
index fef09f721..a8a290083 100644
--- a/src/include/taler_exchange_service.h
+++ b/src/include/taler_exchange_service.h
@@ -1599,6 +1599,11 @@ struct TALER_EXCHANGE_RefreshData
*/
struct TALER_CoinSpendPrivateKeyP melt_priv;
+ /*
+ * age commitment that went into the original coin, might be NULL
+ */
+ struct TALER_AgeCommitment *age_commitment;
+
/**
* amount specifying how much the coin will contribute to the melt
* (including fee)
@@ -1767,6 +1772,12 @@ struct TALER_EXCHANGE_RevealedCoinInfo
struct TALER_PlanchetMasterSecretP ps;
/**
+ * Age commitment and its hash of the coin, might be NULL.
+ */
+ struct TALER_AgeCommitment *age_commitment;
+ struct TALER_AgeCommitmentHash *h_age_commitment;
+
+ /**
* Blinding keys used to blind the fresh coin.
*/
union TALER_DenominationBlindingKeyP bks;
@@ -1982,6 +1993,7 @@ typedef void
*
* @param exchange the exchange handle; the exchange must be ready to operate
* @param coin_priv private key to request link data for
+ * @param age_commitment age commitment to the corresponding coin, might be NULL
* @param link_cb the callback to call with the useful result of the
* refresh operation the @a coin_priv was involved in (if any)
* @param link_cb_cls closure for @a link_cb
@@ -1990,6 +2002,7 @@ typedef void
struct TALER_EXCHANGE_LinkHandle *
TALER_EXCHANGE_link (struct TALER_EXCHANGE_Handle *exchange,
const struct TALER_CoinSpendPrivateKeyP *coin_priv,
+ const struct TALER_AgeCommitment *age_commitment,
TALER_EXCHANGE_LinkCallback link_cb,
void *link_cb_cls);
diff --git a/src/lib/exchange_api_deposit.c b/src/lib/exchange_api_deposit.c
index 2bfaaf6ce..2cd405561 100644
--- a/src/lib/exchange_api_deposit.c
+++ b/src/lib/exchange_api_deposit.c
@@ -518,11 +518,11 @@ verify_signatures (const struct TALER_EXCHANGE_DenomPublicKey *dki,
.coin_pub = *coin_pub,
.denom_pub_hash = *denom_pub_hash,
.denom_sig = *denom_sig,
- .age_commitment_hash = {{{0}}}
+ .h_age_commitment = {{{0}}}
};
if (NULL != h_age_commitment)
{
- coin_info.age_commitment_hash = *h_age_commitment;
+ coin_info.h_age_commitment = *h_age_commitment;
}
if (GNUNET_YES !=
diff --git a/src/lib/exchange_api_link.c b/src/lib/exchange_api_link.c
index 10ddd471d..0702ba4e8 100644
--- a/src/lib/exchange_api_link.c
+++ b/src/lib/exchange_api_link.c
@@ -66,6 +66,11 @@ struct TALER_EXCHANGE_LinkHandle
*/
struct TALER_CoinSpendPrivateKeyP coin_priv;
+ /**
+ * Age commitment of the coin, might be NULL, required to re-generate age commitments
+ */
+ const struct TALER_AgeCommitment *age_commitment;
+
};
@@ -113,7 +118,7 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh,
struct TALER_TransferSecretP secret;
struct TALER_PlanchetDetail pd;
struct TALER_CoinPubHash c_hash;
- struct TALER_AgeCommitmentHash h_age_commitment = {0}; // TODO, see below.
+ struct TALER_AgeCommitmentHash *hac = NULL;
/* parse reply */
memset (&nonce,
@@ -139,12 +144,37 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh,
TALER_planchet_blinding_secret_create (&lci->ps,
&alg_values,
&bks);
+
+ /* Derive the age commitment and calculate the hash */
+ if (NULL != lh->age_commitment)
+ {
+ struct TALER_AgeCommitment nac = {0};
+ struct TALER_AgeCommitmentHash h = {0};
+ uint32_t seed = secret.key.bits[0];
+
+ if (GNUNET_OK !=
+ TALER_age_commitment_derive (
+ lh->age_commitment,
+ seed,
+ &nac))
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+
+ TALER_age_commitment_hash (
+ &nac,
+ &h);
+
+ hac = &h;
+ }
+
if (GNUNET_OK !=
TALER_planchet_prepare (&rpub,
&alg_values,
&bks,
&lci->coin_priv,
- NULL, /* FIXME-oec. struct TALER_AgeCommitmentHash */
+ hac,
&c_hash,
&pd))
{
@@ -181,14 +211,6 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh,
GNUNET_CRYPTO_eddsa_key_get_public (&lh->coin_priv.eddsa_priv,
&old_coin_pub.eddsa_pub);
- /*
- * TODO-oec: Derive the age commitment vector and hash it into
- * h_age_commitment.
- * Questions:
- * - Where do we get the information about the support for age
- * restriction of the denomination?
- * - Where do we get the information bout the previous coin's age groups?
- */
TALER_coin_ev_hash (&pd.blinded_planchet,
&pd.denom_pub_hash,
@@ -198,7 +220,6 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh,
trans_pub,
&coin_envelope_hash,
&old_coin_pub,
- &h_age_commitment,
&link_sig))
{
GNUNET_break_op (0);
@@ -455,6 +476,7 @@ handle_link_finished (void *cls,
struct TALER_EXCHANGE_LinkHandle *
TALER_EXCHANGE_link (struct TALER_EXCHANGE_Handle *exchange,
const struct TALER_CoinSpendPrivateKeyP *coin_priv,
+ const struct TALER_AgeCommitment *age_commitment,
TALER_EXCHANGE_LinkCallback link_cb,
void *link_cb_cls)
{
@@ -493,6 +515,7 @@ TALER_EXCHANGE_link (struct TALER_EXCHANGE_Handle *exchange,
lh->link_cb = link_cb;
lh->link_cb_cls = link_cb_cls;
lh->coin_priv = *coin_priv;
+ lh->age_commitment = age_commitment;
lh->url = TEAH_path_to_url (exchange,
arg_str);
if (NULL == lh->url)
diff --git a/src/lib/exchange_api_management_get_keys.c b/src/lib/exchange_api_management_get_keys.c
index ac419388f..4d6866338 100644
--- a/src/lib/exchange_api_management_get_keys.c
+++ b/src/lib/exchange_api_management_get_keys.c
@@ -32,7 +32,7 @@
/**
* Set to 1 for extra debug logging.
*/
-#define DEBUG 1 /* FIXME-oec */
+#define DEBUG 0
/**
diff --git a/src/lib/exchange_api_refresh_common.c b/src/lib/exchange_api_refresh_common.c
index 89ee1e178..30711d781 100644
--- a/src/lib/exchange_api_refresh_common.c
+++ b/src/lib/exchange_api_refresh_common.c
@@ -77,6 +77,8 @@ TALER_EXCHANGE_get_melt_data_ (
md->melted_coin.fee_melt = rd->melt_pk.fee_refresh;
md->melted_coin.original_value = rd->melt_pk.value;
md->melted_coin.expire_deposit = rd->melt_pk.expire_deposit;
+ md->melted_coin.age_commitment = rd->age_commitment;
+
GNUNET_assert (GNUNET_OK ==
TALER_amount_set_zero (rd->melt_amount.currency,
&total));
@@ -141,14 +143,18 @@ TALER_EXCHANGE_get_melt_data_ (
rms,
i,
&md->transfer_priv[i]);
+
GNUNET_CRYPTO_ecdhe_key_get_public (
&md->transfer_priv[i].ecdhe_priv,
&md->transfer_pub[i].ecdhe_pub);
+
TALER_link_derive_transfer_secret (&rd->melt_priv,
&md->transfer_priv[i],
&trans_sec);
+
md->rcd[i] = GNUNET_new_array (rd->fresh_pks_len,
struct TALER_RefreshCoinData);
+
for (unsigned int j = 0; j<rd->fresh_pks_len; j++)
{
struct FreshCoinData *fcd = &md->fcds[j];
@@ -158,24 +164,57 @@ TALER_EXCHANGE_get_melt_data_ (
union TALER_DenominationBlindingKeyP *bks = &fcd->bks[i];
struct TALER_PlanchetDetail pd;
struct TALER_CoinPubHash c_hash;
+ struct TALER_AgeCommitmentHash *ach = NULL;
TALER_transfer_secret_to_planchet_secret (&trans_sec,
j,
ps);
+
TALER_planchet_setup_coin_priv (ps,
&alg_values[j],
coin_priv);
+
TALER_planchet_blinding_secret_create (ps,
&alg_values[j],
bks);
+
+ /* Handle age commitment, if present */
+ if (NULL != md->melted_coin.age_commitment)
+ {
+ struct TALER_AgeCommitment new_ac;
+ struct TALER_AgeCommitmentHash hac;
+
+ /* We use the first 4 bytes of the trans_sec to generate a new age
+ * commitment */
+ uint32_t age_seed = trans_sec.key.bits[0];
+
+ if (GNUNET_OK !=
+ TALER_age_commitment_derive (
+ md->melted_coin.age_commitment,
+ age_seed + j,
+ &new_ac))
+ {
+ GNUNET_break_op (0);
+ TALER_EXCHANGE_free_melt_data_ (md);
+ return GNUNET_SYSERR;
+ }
+
+ TALER_age_commitment_hash (
+ &new_ac,
+ &hac);
+
+ ach = &hac;
+ }
+
if (TALER_DENOMINATION_CS == alg_values[j].cipher)
pd.blinded_planchet.details.cs_blinded_planchet.nonce = nonces[j];
+
if (GNUNET_OK !=
TALER_planchet_prepare (&fcd->fresh_pk,
&alg_values[j],
bks,
coin_priv,
- NULL, /* FIXME-oec: This needs to be setup !*/
+ ach,
&c_hash,
&pd))
{
@@ -183,6 +222,7 @@ TALER_EXCHANGE_get_melt_data_ (
TALER_EXCHANGE_free_melt_data_ (md);
return GNUNET_SYSERR;
}
+
rcd->blinded_planchet = pd.blinded_planchet;
rcd->dk = &fcd->fresh_pk;
}
diff --git a/src/lib/exchange_api_refresh_common.h b/src/lib/exchange_api_refresh_common.h
index b6926b51f..a3c3e2c02 100644
--- a/src/lib/exchange_api_refresh_common.h
+++ b/src/lib/exchange_api_refresh_common.h
@@ -53,10 +53,11 @@ struct MeltedCoin
struct TALER_Amount original_value;
/**
- * The original age commitment hash. MUST be all zeroes, if no age
+ * The original age commitment and its hash. MUST be NULL if no age
* commitment was set.
*/
- struct TALER_AgeCommitmentHash h_age_commitment;
+ struct TALER_AgeCommitment *age_commitment;
+ struct TALER_AgeCommitmentHash *h_age_commitment;
/**
* Timestamp indicating when coins of this denomination become invalid.
diff --git a/src/lib/exchange_api_refreshes_reveal.c b/src/lib/exchange_api_refreshes_reveal.c
index 8d04c279a..d5f2265c4 100644
--- a/src/lib/exchange_api_refreshes_reveal.c
+++ b/src/lib/exchange_api_refreshes_reveal.c
@@ -142,7 +142,6 @@ refresh_reveal_ok (struct TALER_EXCHANGE_RefreshesRevealHandle *rrh,
&rcis[i];
const struct FreshCoinData *fcd = &rrh->md.fcds[i];
const struct TALER_DenominationPublicKey *pk;
- struct TALER_AgeCommitmentHash *ach = NULL;
json_t *jsonai;
struct TALER_BlindedDenominationSignature blind_sig;
struct TALER_CoinSpendPublicKeyP coin_pub;
@@ -157,14 +156,22 @@ refresh_reveal_ok (struct TALER_EXCHANGE_RefreshesRevealHandle *rrh,
rci->ps = fcd->ps[rrh->noreveal_index];
rci->bks = fcd->bks[rrh->noreveal_index];
+ rci->age_commitment = fcd->age_commitment[rrh->noreveal_index];
+ rci->h_age_commitment = NULL;
pk = &fcd->fresh_pk;
jsonai = json_array_get (jsona, i);
+
GNUNET_assert (NULL != jsonai);
+ GNUNET_assert (
+ (NULL != rrh->md.melted_coin.age_commitment) ==
+ (NULL != rci->age_commitment));
- if (! TALER_AgeCommitmentHash_isNullOrZero (
- &rrh->md.melted_coin.h_age_commitment))
+ if (NULL != rci->age_commitment)
{
- /* FIXME-oec: need to pull fresh_ach from somewhere */
+ rci->h_age_commitment = GNUNET_new (struct TALER_AgeCommitmentHash);
+ TALER_age_commitment_hash (
+ rci->age_commitment,
+ rci->h_age_commitment);
}
if (GNUNET_OK !=
@@ -188,14 +195,14 @@ refresh_reveal_ok (struct TALER_EXCHANGE_RefreshesRevealHandle *rrh,
GNUNET_CRYPTO_eddsa_key_get_public (&rci->coin_priv.eddsa_priv,
&coin_pub.eddsa_pub);
TALER_coin_pub_hash (&coin_pub,
- ach,
+ rci->h_age_commitment,
&coin_hash);
if (GNUNET_OK !=
TALER_planchet_to_coin (pk,
&blind_sig,
&bks,
&rci->coin_priv,
- ach,
+ rci->h_age_commitment,
&coin_hash,
&rrh->alg_values[i],
&coin))
diff --git a/src/testing/test_exchange_api_twisted.c b/src/testing/test_exchange_api_twisted.c
index 33631764c..f8cfa64b7 100644
--- a/src/testing/test_exchange_api_twisted.c
+++ b/src/testing/test_exchange_api_twisted.c
@@ -124,6 +124,7 @@ run (void *cls,
TALER_TESTING_cmd_withdraw_amount ("refresh-withdraw-coin",
"refresh-create-reserve",
"EUR:5",
+ 0, /* age restriction off */
MHD_HTTP_OK),
TALER_TESTING_cmd_deposit ("refresh-deposit-partial",
"refresh-withdraw-coin",
@@ -164,6 +165,7 @@ run (void *cls,
TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-r1",
"create-reserve-r1",
"EUR:5",
+ 0, /* age restriction off */
MHD_HTTP_OK),
TALER_TESTING_cmd_deposit ("deposit-refund-1",
"withdraw-coin-r1",
@@ -233,6 +235,7 @@ run (void *cls,
TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-r2",
"create-reserve-r2",
"EUR:5",
+ 0, /* age restriction off */
MHD_HTTP_OK),
TALER_TESTING_cmd_end ()
};
diff --git a/src/testing/testing_api_cmd_insert_deposit.c b/src/testing/testing_api_cmd_insert_deposit.c
index dcda7cf33..f02040677 100644
--- a/src/testing/testing_api_cmd_insert_deposit.c
+++ b/src/testing/testing_api_cmd_insert_deposit.c
@@ -212,7 +212,7 @@ insert_deposit_run (void *cls,
GNUNET_assert (GNUNET_OK ==
TALER_denom_blind (&dpk,
&bks,
- NULL, /* FIXME-Oec */
+ NULL, /* no age restriction active */
&deposit.coin.coin_pub,
&alg_values,
&c_hash,
diff --git a/src/testing/testing_api_cmd_refresh.c b/src/testing/testing_api_cmd_refresh.c
index 11c88c19c..8ae4ab93f 100644
--- a/src/testing/testing_api_cmd_refresh.c
+++ b/src/testing/testing_api_cmd_refresh.c
@@ -836,6 +836,7 @@ refresh_link_run (void *cls,
/* finally, use private key from withdraw sign command */
rls->rlh = TALER_EXCHANGE_link (is->exchange,
coin_priv,
+ rms->age_commitment,
&link_cb,
rls);
@@ -1149,28 +1150,29 @@ melt_run (void *cls,
rms->refresh_data.melt_pk = *melt_denom_pub;
rms->refresh_data.fresh_pks = rms->fresh_pks;
rms->refresh_data.fresh_pks_len = num_fresh_coins;
-/* FIXME-oec: is this needed _here_?
+ rms->refresh_data.age_commitment = NULL;
+
+ GNUNET_assert (age_restricted ==
+ (NULL != rms->age_commitment));
+
+ if (NULL != rms->age_commitment)
{
- struct TALER_AgeCommitment *ac = NULL;
+ struct TALER_AgeCommitment *ac;
+ uint32_t seed;
- GNUNET_assert (age_restricted == (NULL != rms->age_commitment));
+ ac = GNUNET_new (struct TALER_AgeCommitment);
+ seed = GNUNET_CRYPTO_random_u32 (
+ GNUNET_CRYPTO_QUALITY_WEAK,
+ UINT32_MAX);
- if (NULL != rms->age_commitment)
- {
- uint32_t seed = GNUNET_CRYPTO_random_u32 (
- GNUNET_CRYPTO_QUALITY_WEAK,
- UINT32_MAX);
-
- GNUNET_assert (GNUNET_OK ==
- TALER_age_commitment_derive (
- rms->age_commitment,
- seed,
- ac));
- }
+ GNUNET_assert (GNUNET_OK ==
+ TALER_age_commitment_derive (
+ rms->age_commitment,
+ seed,
+ ac));
- rms->refresh_data.age_commitment = ac
+ rms->refresh_data.age_commitment = ac;
}
-*/
rms->rmh = TALER_EXCHANGE_melt (is->exchange,
&rms->rms,
diff --git a/src/util/crypto.c b/src/util/crypto.c
index 6bea984f3..39a9c7f17 100644
--- a/src/util/crypto.c
+++ b/src/util/crypto.c
@@ -90,7 +90,7 @@ TALER_test_coin_valid (const struct TALER_CoinPublicInfo *coin_public_info,
#endif
TALER_coin_pub_hash (&coin_public_info->coin_pub,
- &coin_public_info->age_commitment_hash,
+ &coin_public_info->h_age_commitment,
&c_hash);
if (GNUNET_OK !=
@@ -681,7 +681,7 @@ FAIL:
void
-TALER_age_restriction_commmitment_free_inside (
+TALER_age_commitment_free (
struct TALER_AgeCommitment *commitment)
{
if (NULL == commitment)
@@ -703,7 +703,7 @@ TALER_age_restriction_commmitment_free_inside (
commitment->priv = NULL;
}
- /* Caller is responsible for commitment itself */
+ GNUNET_free (commitment);
}
diff --git a/src/util/wallet_signatures.c b/src/util/wallet_signatures.c
index 88cd8de06..6c664bbd3 100644
--- a/src/util/wallet_signatures.c
+++ b/src/util/wallet_signatures.c
@@ -143,7 +143,6 @@ TALER_wallet_link_verify (
const struct TALER_TransferPublicKeyP *transfer_pub,
const struct TALER_BlindedCoinHash *h_coin_ev,
const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
- const struct TALER_AgeCommitmentHash *h_age_commitment,
const struct TALER_CoinSpendSignatureP *coin_sig)
{
struct TALER_LinkDataPS ldp = {
@@ -152,12 +151,8 @@ TALER_wallet_link_verify (
.h_denom_pub = *h_denom_pub,
.transfer_pub = *transfer_pub,
.coin_envelope_hash = *h_coin_ev,
- .h_age_commitment = {{{0}}}
};
- if (NULL != h_age_commitment)
- ldp.h_age_commitment = *h_age_commitment;
-
return
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_LINK,
&ldp,