From f32ef1f64b7b49e07609eacd11bf0e50736da87e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96zg=C3=BCr=20Kesim?= Date: Sun, 13 Feb 2022 23:57:43 +0100 Subject: [PATCH] Withdraw and deposit works with age restriction The following tests work: - Withdraw coins with age (13) from age restricted denominations - Deposit that coin (purchase) Now to do: - refresh - link - refund --- src/auditor/taler-helper-auditor-coins.c | 2 ++ src/exchange/taler-exchange-httpd_deposit.c | 4 +++ src/exchange/taler-exchange-httpd_responses.c | 1 + src/exchangedb/plugin_exchangedb_postgres.c | 3 +- src/include/taler_crypto_lib.h | 4 +++ src/include/taler_exchange_service.h | 3 +- src/include/taler_signatures.h | 6 ++++ src/lib/exchange_api_common.c | 2 ++ src/lib/exchange_api_deposit.c | 29 ++++++------------- src/lib/exchange_api_refund.c | 5 ++++ src/testing/test_exchange_api.c | 9 ++++-- src/testing/testing_api_cmd_deposit.c | 19 +++++++----- src/testing/testing_api_cmd_withdraw.c | 2 -- src/util/crypto.c | 17 ++--------- src/util/wallet_signatures.c | 29 ++++++++++++++----- 15 files changed, 77 insertions(+), 58 deletions(-) diff --git a/src/auditor/taler-helper-auditor-coins.c b/src/auditor/taler-helper-auditor-coins.c index a54f7307a..5bb9ae3ea 100644 --- a/src/auditor/taler-helper-auditor-coins.c +++ b/src/auditor/taler-helper-auditor-coins.c @@ -1617,6 +1617,7 @@ 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); @@ -1633,6 +1634,7 @@ deposit_cb (void *cls, &deposit_fee, &h_wire, &deposit->h_contract_terms, + h_age_commitment, /* FIXME-oec */ NULL /* h_extensions! */, &h_denom_pub, deposit->timestamp, diff --git a/src/exchange/taler-exchange-httpd_deposit.c b/src/exchange/taler-exchange-httpd_deposit.c index 84741b5c3..c3efd9ff5 100644 --- a/src/exchange/taler-exchange-httpd_deposit.c +++ b/src/exchange/taler-exchange-httpd_deposit.c @@ -239,6 +239,9 @@ TEH_handler_deposit (struct MHD_Connection *connection, &deposit.merchant_pub), GNUNET_JSON_spec_fixed_auto ("h_contract_terms", &deposit.h_contract_terms), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_fixed_auto ("h_age_commitment", + &deposit.coin.age_commitment_hash)), GNUNET_JSON_spec_fixed_auto ("coin_sig", &deposit.csig), GNUNET_JSON_spec_timestamp ("timestamp", @@ -387,6 +390,7 @@ TEH_handler_deposit (struct MHD_Connection *connection, &deposit.deposit_fee, &h_wire, &deposit.h_contract_terms, + &deposit.coin.age_commitment_hash, NULL /* h_extensions! */, &deposit.coin.denom_pub_hash, deposit.timestamp, diff --git a/src/exchange/taler-exchange-httpd_responses.c b/src/exchange/taler-exchange-httpd_responses.c index d1a6d68fe..96bff2eff 100644 --- a/src/exchange/taler-exchange-httpd_responses.c +++ b/src/exchange/taler-exchange-httpd_responses.c @@ -73,6 +73,7 @@ TEH_RESPONSE_compile_transaction_history ( &deposit->deposit_fee, &h_wire, &deposit->h_contract_terms, + NULL, /* h_age_commitment, FIXME-oec */ NULL /* h_extensions! */, &deposit->h_denom_pub, deposit->timestamp, diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c index 02dbcae5e..c0ff9acdf 100644 --- a/src/exchangedb/plugin_exchangedb_postgres.c +++ b/src/exchangedb/plugin_exchangedb_postgres.c @@ -5789,7 +5789,6 @@ postgres_ensure_coin_known (void *cls, GNUNET_PQ_result_spec_end }; - GNUNET_break (GNUNET_is_zero (&coin->age_commitment_hash)); // FIXME-OEC qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, "insert_known_coin", params, @@ -5822,7 +5821,7 @@ postgres_ensure_coin_known (void *cls, (0 != GNUNET_memcmp (age_hash, &coin->age_commitment_hash)) ) { - GNUNET_break (GNUNET_is_zero (age_hash)); // FIXME-OEC + GNUNET_break (GNUNET_is_zero (age_hash)); GNUNET_break_op (0); return TALER_EXCHANGEDB_CKS_AGE_CONFLICT; } diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h index d0abaa75f..b755d26b5 100644 --- a/src/include/taler_crypto_lib.h +++ b/src/include/taler_crypto_lib.h @@ -1720,6 +1720,7 @@ TALER_exchange_deposit_confirm_verify ( * @param deposit_fee the deposit fee we expect to pay * @param h_wire hash of the merchant’s account details * @param h_contract_terms hash of the contact of the merchant with the customer (further details are never disclosed to the exchange) + * @param h_age_commitment hash over the age commitment, if applicable to the denomination (maybe NULL) * @param h_extensions hash over the extensions * @param h_denom_pub hash of the coin denomination's public key * @param coin_priv coin’s private key @@ -1734,6 +1735,7 @@ TALER_wallet_deposit_sign ( const struct TALER_Amount *deposit_fee, const struct TALER_MerchantWireHash *h_wire, const struct TALER_PrivateContractHash *h_contract_terms, + const struct TALER_AgeCommitmentHash *h_age_commitment, const struct TALER_ExtensionContractHash *h_extensions, const struct TALER_DenominationHash *h_denom_pub, struct GNUNET_TIME_Timestamp wallet_timestamp, @@ -1750,6 +1752,7 @@ TALER_wallet_deposit_sign ( * @param deposit_fee the deposit fee we expect to pay * @param h_wire hash of the merchant’s account details * @param h_contract_terms hash of the contact of the merchant with the customer (further details are never disclosed to the exchange) + * @param h_age_commitment hash over the age commitment (maybe all zeroes, if not applicable to the denomination) * @param h_extensions hash over the extensions * @param h_denom_pub hash of the coin denomination's public key * @param wallet_timestamp timestamp when the contract was finalized, must not be too far in the future @@ -1765,6 +1768,7 @@ TALER_wallet_deposit_verify ( const struct TALER_Amount *deposit_fee, const struct TALER_MerchantWireHash *h_wire, const struct TALER_PrivateContractHash *h_contract_terms, + const struct TALER_AgeCommitmentHash *h_commitment_hash, const struct TALER_ExtensionContractHash *h_extensions, const struct TALER_DenominationHash *h_denom_pub, struct GNUNET_TIME_Timestamp wallet_timestamp, diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index ce4cd0214..8e361e5ec 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -901,7 +901,6 @@ typedef void * @param h_contract_terms hash of the contact of the merchant with the customer (further details are never disclosed to the exchange) * @param extension_details extension-specific details about the deposit relevant to the exchange * @param coin_pub coin’s public key - * @param age_commitment age commitment that went into the making of the coin, might be NULL * @param denom_pub denomination key with which the coin is signed * @param denom_sig exchange’s unblinded signature of the coin * @param timestamp timestamp when the contract was finalized, must match approximately the current time of the exchange @@ -922,9 +921,9 @@ TALER_EXCHANGE_deposit ( const char *merchant_payto_uri, const struct TALER_WireSalt *wire_salt, const struct TALER_PrivateContractHash *h_contract_terms, + const struct TALER_AgeCommitmentHash *h_age_commitment, const json_t *extension_details, const struct TALER_CoinSpendPublicKeyP *coin_pub, - const struct TALER_AgeCommitment *age_commitment, const struct TALER_DenominationSignature *denom_sig, const struct TALER_DenominationPublicKey *denom_pub, struct GNUNET_TIME_Timestamp timestamp, diff --git a/src/include/taler_signatures.h b/src/include/taler_signatures.h index 5671d34f7..7ea01f211 100644 --- a/src/include/taler_signatures.h +++ b/src/include/taler_signatures.h @@ -483,6 +483,12 @@ struct TALER_DepositRequestPS */ struct TALER_PrivateContractHash h_contract_terms 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; + /** * Hash over extension attributes shared with the exchange. */ diff --git a/src/lib/exchange_api_common.c b/src/lib/exchange_api_common.c index 1d41918f8..37d359573 100644 --- a/src/lib/exchange_api_common.c +++ b/src/lib/exchange_api_common.c @@ -482,6 +482,7 @@ TALER_EXCHANGE_verify_coin_history ( struct TALER_MerchantPublicKeyP merchant_pub; struct GNUNET_TIME_Timestamp refund_deadline = {0}; struct TALER_CoinSpendSignatureP sig; + struct TALER_AgeCommitmentHash *hac = NULL; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("coin_sig", &sig), @@ -516,6 +517,7 @@ TALER_EXCHANGE_verify_coin_history ( &fee, &h_wire, &h_contract_terms, + hac, NULL /* h_extensions! */, h_denom_pub, wallet_timestamp, diff --git a/src/lib/exchange_api_deposit.c b/src/lib/exchange_api_deposit.c index fd85be8ed..153f46505 100644 --- a/src/lib/exchange_api_deposit.c +++ b/src/lib/exchange_api_deposit.c @@ -479,7 +479,7 @@ verify_signatures (const struct TALER_EXCHANGE_DenomPublicKey *dki, const struct TALER_PrivateContractHash *h_contract_terms, const struct TALER_ExtensionContractHash *ech, const struct TALER_CoinSpendPublicKeyP *coin_pub, - const struct TALER_AgeCommitmentHash *ach, + const struct TALER_AgeCommitmentHash *h_age_commitment, const struct TALER_DenominationSignature *denom_sig, const struct TALER_DenominationPublicKey *denom_pub, const struct TALER_DenominationHash *denom_pub_hash, @@ -493,6 +493,7 @@ verify_signatures (const struct TALER_EXCHANGE_DenomPublicKey *dki, &dki->fee_deposit, h_wire, h_contract_terms, + h_age_commitment, ech, denom_pub_hash, timestamp, @@ -518,9 +519,9 @@ verify_signatures (const struct TALER_EXCHANGE_DenomPublicKey *dki, .denom_sig = *denom_sig, .age_commitment_hash = {{{0}}} }; - if (NULL != ach) + if (NULL != h_age_commitment) { - coin_info.age_commitment_hash = *ach; + coin_info.age_commitment_hash = *h_age_commitment; } if (GNUNET_YES != @@ -553,9 +554,9 @@ TALER_EXCHANGE_deposit ( const char *merchant_payto_uri, const struct TALER_WireSalt *wire_salt, const struct TALER_PrivateContractHash *h_contract_terms, + const struct TALER_AgeCommitmentHash *h_age_commitment, const json_t *extension_details, const struct TALER_CoinSpendPublicKeyP *coin_pub, - const struct TALER_AgeCommitment *age_commitment, const struct TALER_DenominationSignature *denom_sig, const struct TALER_DenominationPublicKey *denom_pub, struct GNUNET_TIME_Timestamp timestamp, @@ -576,7 +577,6 @@ TALER_EXCHANGE_deposit ( struct TALER_DenominationHash denom_pub_hash; struct TALER_Amount amount_without_fee; struct TALER_ExtensionContractHash ech; - struct TALER_AgeCommitmentHash ach; char arg_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2 + 32]; if (NULL != extension_details) @@ -637,20 +637,6 @@ TALER_EXCHANGE_deposit ( TALER_denom_pub_hash (denom_pub, &denom_pub_hash); - if (NULL != age_commitment) - { - TALER_age_commitment_hash (age_commitment, &ach); - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "XXXXXX deposit WITH age commitment %s\n", - GNUNET_h2s ((struct GNUNET_HashCode *) &ach.shash)); - } - else - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "XXXXXX deposit with NO age commitment\n"); - } - - if (GNUNET_OK != verify_signatures (dki, amount, @@ -658,7 +644,7 @@ TALER_EXCHANGE_deposit ( h_contract_terms, (NULL != extension_details) ? &ech : NULL, coin_pub, - (NULL != age_commitment) ? &ach : NULL, + h_age_commitment, denom_sig, denom_pub, &denom_pub_hash, @@ -681,6 +667,9 @@ TALER_EXCHANGE_deposit ( wire_salt), GNUNET_JSON_pack_data_auto ("h_contract_terms", h_contract_terms), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_data_auto ("h_age_commitment", + h_age_commitment)), GNUNET_JSON_pack_data_auto ("denom_pub_hash", &denom_pub_hash), TALER_JSON_pack_denom_sig ("ub_sig", diff --git a/src/lib/exchange_api_refund.c b/src/lib/exchange_api_refund.c index 94909470a..a9510715b 100644 --- a/src/lib/exchange_api_refund.c +++ b/src/lib/exchange_api_refund.c @@ -203,6 +203,7 @@ verify_conflict_history_ok (struct TALER_EXCHANGE_RefundHandle *rh, struct TALER_Amount deposit_fee; struct TALER_MerchantWireHash h_wire; struct TALER_PrivateContractHash h_contract_terms; + struct TALER_AgeCommitmentHash h_age_commitment = {{{0}}}; // struct TALER_ExtensionContractHash h_extensions; // FIXME! struct TALER_DenominationHash h_denom_pub; struct GNUNET_TIME_Timestamp wallet_timestamp; @@ -218,6 +219,9 @@ verify_conflict_history_ok (struct TALER_EXCHANGE_RefundHandle *rh, &h_wire), GNUNET_JSON_spec_fixed_auto ("h_denom_pub", &h_denom_pub), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_fixed_auto ("h_age_commitment", + &h_age_commitment)), GNUNET_JSON_spec_timestamp ("timestamp", &wallet_timestamp), GNUNET_JSON_spec_timestamp ("refund_deadline", @@ -243,6 +247,7 @@ verify_conflict_history_ok (struct TALER_EXCHANGE_RefundHandle *rh, &deposit_fee, &h_wire, &h_contract_terms, + &h_age_commitment, NULL /* h_extensions! */, &h_denom_pub, wallet_timestamp, diff --git a/src/testing/test_exchange_api.c b/src/testing/test_exchange_api.c index a42afb9ff..0348b265c 100644 --- a/src/testing/test_exchange_api.c +++ b/src/testing/test_exchange_api.c @@ -349,9 +349,9 @@ run (void *cls, * Move money to the exchange's bank account. */ CMD_TRANSFER_TO_EXCHANGE ("create-reserve-age", - "EUR:6.02"), + "EUR:5.02"), TALER_TESTING_cmd_check_bank_admin_transfer ("check-create-reserve-age", - "EUR:6.02", + "EUR:5.02", bc.user42_payto, bc.exchange_payto, "create-reserve-age"), @@ -432,6 +432,11 @@ run (void *cls, "EUR:4.98", bc.exchange_payto, bc.user42_payto), + TALER_TESTING_cmd_check_bank_transfer ("check_bank_transfer-499c2", + ec.exchange_url, + "EUR:4.98", + bc.exchange_payto, + bc.user42_payto), TALER_TESTING_cmd_check_bank_transfer ("check_bank_transfer-99c1", ec.exchange_url, "EUR:0.98", diff --git a/src/testing/testing_api_cmd_deposit.c b/src/testing/testing_api_cmd_deposit.c index 52181c6ce..67c2c7021 100644 --- a/src/testing/testing_api_cmd_deposit.c +++ b/src/testing/testing_api_cmd_deposit.c @@ -287,7 +287,8 @@ deposit_run (void *cls, const struct TALER_TESTING_Command *coin_cmd; const struct TALER_CoinSpendPrivateKeyP *coin_priv; struct TALER_CoinSpendPublicKeyP coin_pub; - struct TALER_AgeCommitment *pac = NULL; + struct TALER_AgeCommitment *age_commitment = NULL; + struct TALER_AgeCommitmentHash h_age_commitment = {0}; const struct TALER_EXCHANGE_DenomPublicKey *denom_pub; const struct TALER_DenominationSignature *denom_pub_sig; struct TALER_CoinSpendSignatureP coin_sig; @@ -386,7 +387,7 @@ deposit_run (void *cls, (GNUNET_OK != TALER_TESTING_get_trait_age_commitment (coin_cmd, ds->coin_index, - &pac)) || + &age_commitment)) || (GNUNET_OK != TALER_TESTING_get_trait_denom_pub (coin_cmd, ds->coin_index, @@ -404,9 +405,10 @@ deposit_run (void *cls, return; } - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "XZXZXZXZ pac is %sNULL\n", - (NULL == pac)? "" : "NOT "); + if (NULL != age_commitment) + { + TALER_age_commitment_hash (age_commitment, &h_age_commitment); + } ds->deposit_fee = denom_pub->fee_deposit; GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv->eddsa_priv, @@ -441,7 +443,8 @@ deposit_run (void *cls, &denom_pub->fee_deposit, &h_wire, &h_contract_terms, - NULL, /* FIXME: extension hash! */ + &h_age_commitment, + NULL, /* FIXME: add hash of extensions */ &denom_pub->h_key, ds->wallet_timestamp, &merchant_pub, @@ -455,9 +458,9 @@ deposit_run (void *cls, payto_uri, &wire_salt, &h_contract_terms, - NULL, /* FIXME: extension object */ + &h_age_commitment, + NULL, /* FIXME: add hash of extensions */ &coin_pub, - pac, denom_pub_sig, &denom_pub->key, ds->wallet_timestamp, diff --git a/src/testing/testing_api_cmd_withdraw.c b/src/testing/testing_api_cmd_withdraw.c index 37c21cc76..e3c129172 100644 --- a/src/testing/testing_api_cmd_withdraw.c +++ b/src/testing/testing_api_cmd_withdraw.c @@ -608,8 +608,6 @@ TALER_TESTING_cmd_withdraw_amount (const char *label, uint32_t seed; struct TALER_AgeMask mask; - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "AAAAAAA age is %d\n", age); - ac = GNUNET_new (struct TALER_AgeCommitment); hac = GNUNET_new (struct TALER_AgeCommitmentHash); seed = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX); diff --git a/src/util/crypto.c b/src/util/crypto.c index 5a88c6db1..0071c2d72 100644 --- a/src/util/crypto.c +++ b/src/util/crypto.c @@ -88,21 +88,10 @@ TALER_test_coin_valid (const struct TALER_CoinPublicInfo *coin_public_info, GNUNET_memcmp (&d_hash, &coin_public_info->denom_pub_hash)); #endif - { - const struct TALER_AgeCommitmentHash *pahc = - &coin_public_info->age_commitment_hash; - if (TALER_AgeCommitmentHash_isNullOrZero (pahc)) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "ZZZZZZZZ AgeCommitmentHash isNUllOrZero!!\n"); - pahc = NULL; - } - - TALER_coin_pub_hash (&coin_public_info->coin_pub, - pahc, - &c_hash); - } + TALER_coin_pub_hash (&coin_public_info->coin_pub, + &coin_public_info->age_commitment_hash, + &c_hash); if (GNUNET_OK != TALER_denom_pub_verify (denom_pub, diff --git a/src/util/wallet_signatures.c b/src/util/wallet_signatures.c index a608046a0..00ec2bc24 100644 --- a/src/util/wallet_signatures.c +++ b/src/util/wallet_signatures.c @@ -29,6 +29,7 @@ TALER_wallet_deposit_sign ( const struct TALER_Amount *deposit_fee, const struct TALER_MerchantWireHash *h_wire, const struct TALER_PrivateContractHash *h_contract_terms, + const struct TALER_AgeCommitmentHash *h_age_commitment, const struct TALER_ExtensionContractHash *h_extensions, const struct TALER_DenominationHash *h_denom_pub, struct GNUNET_TIME_Timestamp wallet_timestamp, @@ -48,8 +49,12 @@ TALER_wallet_deposit_sign ( .merchant = *merchant_pub }; + if (NULL != h_age_commitment) + dr.h_age_commitment = *h_age_commitment; + if (NULL != h_extensions) dr.h_extensions = *h_extensions; + TALER_amount_hton (&dr.amount_with_fee, amount); TALER_amount_hton (&dr.deposit_fee, @@ -66,6 +71,7 @@ TALER_wallet_deposit_verify ( const struct TALER_Amount *deposit_fee, const struct TALER_MerchantWireHash *h_wire, const struct TALER_PrivateContractHash *h_contract_terms, + const struct TALER_AgeCommitmentHash *h_age_commitment, const struct TALER_ExtensionContractHash *h_extensions, const struct TALER_DenominationHash *h_denom_pub, struct GNUNET_TIME_Timestamp wallet_timestamp, @@ -82,11 +88,21 @@ TALER_wallet_deposit_verify ( .h_denom_pub = *h_denom_pub, .wallet_timestamp = GNUNET_TIME_timestamp_hton (wallet_timestamp), .refund_deadline = GNUNET_TIME_timestamp_hton (refund_deadline), - .merchant = *merchant_pub + .merchant = *merchant_pub, + .h_age_commitment = {{{0}}}, + .h_extensions = {{{0}}} }; + if (NULL != h_age_commitment) + { + dr.h_age_commitment = *h_age_commitment; + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "VFVFVFVF got NON-NULL h_age_commitment\n"); + } + if (NULL != h_extensions) dr.h_extensions = *h_extensions; + TALER_amount_hton (&dr.amount_with_fee, amount); TALER_amount_hton (&dr.deposit_fee, @@ -143,14 +159,11 @@ TALER_wallet_link_verify ( .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_LINK), .h_denom_pub = *h_denom_pub, .transfer_pub = *transfer_pub, - .coin_envelope_hash = *h_coin_ev + .coin_envelope_hash = *h_coin_ev, + .h_age_commitment = {{{0}}} }; - if (NULL == h_age_commitment) - memset (&ldp.h_age_commitment, - 0, - sizeof(*h_age_commitment)); - else + if (NULL != h_age_commitment) ldp.h_age_commitment = *h_age_commitment; return @@ -284,9 +297,9 @@ TALER_wallet_melt_verify ( .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_MELT), .rc = *rc, .h_denom_pub = *h_denom_pub, + .h_age_commitment = {{{0}}}, }; - memset (&melt.h_age_commitment, 0, sizeof(struct TALER_AgeCommitmentHash)); if (NULL != h_age_commitment) melt.h_age_commitment = *h_age_commitment;