diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/auditor/taler-helper-auditor-coins.c | 5 | ||||
-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 | ||||
-rw-r--r-- | src/exchangedb/plugin_exchangedb_postgres.c | 6 | ||||
-rw-r--r-- | src/include/taler_crypto_lib.h | 22 | ||||
-rw-r--r-- | src/include/taler_exchange_service.h | 13 | ||||
-rw-r--r-- | src/lib/exchange_api_deposit.c | 4 | ||||
-rw-r--r-- | src/lib/exchange_api_link.c | 45 | ||||
-rw-r--r-- | src/lib/exchange_api_management_get_keys.c | 2 | ||||
-rw-r--r-- | src/lib/exchange_api_refresh_common.c | 42 | ||||
-rw-r--r-- | src/lib/exchange_api_refresh_common.h | 5 | ||||
-rw-r--r-- | src/lib/exchange_api_refreshes_reveal.c | 19 | ||||
-rw-r--r-- | src/testing/test_exchange_api_twisted.c | 6 | ||||
-rw-r--r-- | src/testing/testing_api_cmd_insert_deposit.c | 2 | ||||
-rw-r--r-- | src/testing/testing_api_cmd_refresh.c | 36 | ||||
-rw-r--r-- | src/util/crypto.c | 7 | ||||
-rw-r--r-- | src/util/wallet_signatures.c | 5 |
20 files changed, 260 insertions, 80 deletions
diff --git a/src/auditor/taler-helper-auditor-coins.c b/src/auditor/taler-helper-auditor-coins.c index 1b45fea0b..04a35ee8d 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 5a401abb7..7cd78119a 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 cada8e7b0..1585af71f 100644 --- a/src/exchange/taler-exchange-httpd_melt.c +++ b/src/exchange/taler-exchange-httpd_melt.c @@ -348,7 +348,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)) { @@ -425,8 +425,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 32df3c4c9..0f6bb2460 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 9c0a665b7..9e47f4664 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 @@ -272,6 +278,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; @@ -285,12 +292,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) @@ -562,6 +587,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++) { @@ -587,7 +683,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 478be3b0a..6437ca54d 100644 --- a/src/exchangedb/plugin_exchangedb_postgres.c +++ b/src/exchangedb/plugin_exchangedb_postgres.c @@ -5645,7 +5645,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 @@ -5761,7 +5761,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 }; @@ -5811,7 +5811,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 2843d8209..8a1c7bf12 100644 --- a/src/include/taler_crypto_lib.h +++ b/src/include/taler_crypto_lib.h @@ -1053,7 +1053,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, @@ -2414,11 +2414,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); /** @@ -2428,7 +2429,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 */ @@ -2438,7 +2438,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); @@ -3322,12 +3321,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 df1d4da93..666bf101b 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -1680,6 +1680,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) @@ -1848,6 +1853,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; @@ -2063,6 +2074,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 @@ -2071,6 +2083,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 5a819461c..82ee064b9 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 3cd47a6ff..b15e0d0d7 100644 --- a/src/lib/exchange_api_refresh_common.c +++ b/src/lib/exchange_api_refresh_common.c @@ -78,6 +78,8 @@ TALER_EXCHANGE_get_melt_data_ ( md->melted_coin.fee_melt = rd->melt_pk.fees.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)); @@ -144,14 +146,18 @@ TALER_EXCHANGE_get_melt_data_ ( &rd->melt_priv, 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]; @@ -161,24 +167,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)) { @@ -186,6 +225,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 e87cae2ef..896258903 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 150d3b12c..f8cfa64b7 100644 --- a/src/testing/test_exchange_api_twisted.c +++ b/src/testing/test_exchange_api_twisted.c @@ -124,7 +124,7 @@ run (void *cls, TALER_TESTING_cmd_withdraw_amount ("refresh-withdraw-coin", "refresh-create-reserve", "EUR:5", - 0, /* age */ + 0, /* age restriction off */ MHD_HTTP_OK), TALER_TESTING_cmd_deposit ("refresh-deposit-partial", "refresh-withdraw-coin", @@ -165,7 +165,7 @@ run (void *cls, TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-r1", "create-reserve-r1", "EUR:5", - 0, /* age */ + 0, /* age restriction off */ MHD_HTTP_OK), TALER_TESTING_cmd_deposit ("deposit-refund-1", "withdraw-coin-r1", @@ -235,7 +235,7 @@ run (void *cls, TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-r2", "create-reserve-r2", "EUR:5", - 0, /* age */ + 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 5247ccd7d..b1e732975 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 a2fb4f158..29ad9d2fa 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 d3f3cd3fa..13f692c1b 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 != @@ -689,7 +689,7 @@ FAIL: void -TALER_age_restriction_commmitment_free_inside ( +TALER_age_commitment_free ( struct TALER_AgeCommitment *commitment) { if (NULL == commitment) @@ -710,7 +710,8 @@ TALER_age_restriction_commmitment_free_inside ( GNUNET_free (commitment->pub); 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, |