From a351bfc4b4ca15ce7fd998cf9691e85cf84dc426 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 17 Feb 2022 15:10:14 +0100 Subject: -fix CS nonce reuse check logic --- src/include/taler_amount_lib.h | 12 +++ src/include/taler_crypto_lib.h | 175 +++++++++++++++++++++------------- src/include/taler_exchange_service.h | 153 ++++++++++++++++++++++------- src/include/taler_exchangedb_plugin.h | 141 +++++++++++++++++++-------- src/include/taler_json_lib.h | 29 ++++++ src/include/taler_signatures.h | 51 ++-------- src/include/taler_util.h | 33 +++++++ 7 files changed, 406 insertions(+), 188 deletions(-) (limited to 'src/include') diff --git a/src/include/taler_amount_lib.h b/src/include/taler_amount_lib.h index c6d2f474e..a529cfb84 100644 --- a/src/include/taler_amount_lib.h +++ b/src/include/taler_amount_lib.h @@ -184,6 +184,18 @@ enum GNUNET_GenericReturnValue TALER_amount_is_valid (const struct TALER_Amount *amount); +/** + * Test if the given amount is in the given currency + * + * @param amount amount to check + * @param currency currency to check for + * @return #GNUNET_OK if @a amount is in @a currency + */ +enum GNUNET_GenericReturnValue +TALER_amount_is_currency (const struct TALER_Amount *amount, + const char *currency); + + /** * Convert amount from host to network representation. * diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h index 9bbf29de4..2843d8209 100644 --- a/src/include/taler_crypto_lib.h +++ b/src/include/taler_crypto_lib.h @@ -563,22 +563,6 @@ struct TALER_BlindedCoinHash }; -/** - * Hash used to uniquely represent a withdraw process so as to perform - * idempotency checks (and prevent clients from harmfully replaying withdraw - * operations with problematic variations on the inputs). In the CS case, - * this is a hash over the DK and nonce, while in the RSA case, it is simply a - * hash over the DK and the blinded coin. - */ -struct TALER_WithdrawIdentificationHash -{ - /** - * Actual hash value. - */ - struct GNUNET_HashCode hash; -}; - - /** * Hash used to represent the hash of the public * key of a coin (without blinding). @@ -629,9 +613,99 @@ struct TALER_ExtensionConfigHash }; +/** + * Set of the fees applying to a denomination. + */ +struct TALER_DenomFeeSetNBOP +{ + + /** + * The fee the exchange charges when a coin of this type is withdrawn. + * (can be zero). + */ + struct TALER_AmountNBO withdraw; + + /** + * The fee the exchange charges when a coin of this type is deposited. + * (can be zero). + */ + struct TALER_AmountNBO deposit; + + /** + * The fee the exchange charges when a coin of this type is refreshed. + * (can be zero). + */ + struct TALER_AmountNBO refresh; + + /** + * The fee the exchange charges when a coin of this type is refunded. + * (can be zero). Note that refund fees are charged to the customer; + * if a refund is given, the deposit fee is also refunded. + */ + struct TALER_AmountNBO refund; + +}; + + GNUNET_NETWORK_STRUCT_END +/** + * Set of the fees applying to a denomination. + */ +struct TALER_DenomFeeSet +{ + + /** + * The fee the exchange charges when a coin of this type is withdrawn. + * (can be zero). + */ + struct TALER_Amount withdraw; + + /** + * The fee the exchange charges when a coin of this type is deposited. + * (can be zero). + */ + struct TALER_Amount deposit; + + /** + * The fee the exchange charges when a coin of this type is refreshed. + * (can be zero). + */ + struct TALER_Amount refresh; + + /** + * The fee the exchange charges when a coin of this type is refunded. + * (can be zero). Note that refund fees are charged to the customer; + * if a refund is given, the deposit fee is also refunded. + */ + struct TALER_Amount refund; + +}; + + +/** + * Convert fee set from host to network byte order. + * + * @param[out] nbo where to write the result + * @param fees fee set to convert + */ +void +TALER_denom_fee_set_hton (struct TALER_DenomFeeSetNBOP *nbo, + const struct TALER_DenomFeeSet *fees); + + +/** + * Convert fee set from network to host network byte order. + * + * @param[out] fees where to write the result + * @param nbo fee set to convert + */ +void +TALER_denom_fee_set_ntoh (struct TALER_DenomFeeSet *fees, + const struct TALER_DenomFeeSetNBOP *nbo); + + /** * Hash @a rsa. * @@ -1357,22 +1431,6 @@ TALER_coin_ev_hash (const struct TALER_BlindedPlanchet *blinded_planchet, struct TALER_BlindedCoinHash *bch); -/** - * Compute the hash to uniquely identify a withdraw - * request. - * - * @param blinded_planchet blinded planchet - * @param denom_hash hash of the denomination publick key - * @param[out] wih where to write the hash - * @return #GNUNET_OK when successful, #GNUNET_SYSERR if an internal error occured - */ -enum GNUNET_GenericReturnValue -TALER_withdraw_request_hash ( - const struct TALER_BlindedPlanchet *blinded_planchet, - const struct TALER_DenominationHash *denom_hash, - struct TALER_WithdrawIdentificationHash *wih); - - /** * Compute the hash of a coin. * @@ -1548,16 +1606,19 @@ TALER_transfer_secret_to_planchet_secret ( /** * Derive the @a coin_num transfer private key @a tpriv from a refresh from - * the @a rms seed of the refresh operation. The transfer private key - * derivation is based on the @a ps with a KDF salted by the @a coin_num. + * the @a rms seed and the @a old_coin_pub of the refresh operation. The + * transfer private key derivation is based on the @a ps with a KDF salted by + * the @a coin_num. * * @param rms seed to use for KDF to derive transfer keys + * @param old_coin_priv private key of the old coin * @param cnc_num cut and choose number to include in KDF * @param[out] tpriv value to initialize */ void TALER_planchet_secret_to_transfer_priv ( const struct TALER_RefreshMasterSecretP *rms, + const struct TALER_CoinSpendPrivateKeyP *old_coin_priv, uint32_t cnc_num, struct TALER_TransferPrivateKeyP *tpriv); @@ -1675,8 +1736,8 @@ TALER_planchet_to_coin ( * @param[in,out] hash_context hash context to use */ void -TALER_blinded_planchet_hash (const struct TALER_BlindedPlanchet *bp, - struct GNUNET_HashContext *hash_context); +TALER_blinded_planchet_hash_ (const struct TALER_BlindedPlanchet *bp, + struct GNUNET_HashContext *hash_context); /** @@ -1769,6 +1830,7 @@ struct TALER_RefreshCommitmentEntry * * @param[out] rc set to the value the wallet must commit to * @param kappa number of transfer public keys involved (must be #TALER_CNC_KAPPA) + * @param rms refresh master secret to include, can be NULL! * @param num_new_coins number of new coins to be created * @param rcs array of @a kappa commitments * @param coin_pub public key of the coin to be melted @@ -1777,6 +1839,7 @@ struct TALER_RefreshCommitmentEntry void TALER_refresh_get_commitment (struct TALER_RefreshCommitmentP *rc, uint32_t kappa, + const struct TALER_RefreshMasterSecretP *rms, uint32_t num_new_coins, const struct TALER_RefreshCommitmentEntry *rcs, const struct TALER_CoinSpendPublicKeyP *coin_pub, @@ -2724,10 +2787,7 @@ TALER_exchange_offline_signkey_validity_verify ( * @param stamp_expire_deposit how long does the exchange accept the deposit of coins with this key * @param stamp_expire_legal how long does the exchange preserve information for legal disputes with this key * @param coin_value what is the value of coins signed with this key - * @param fee_withdraw what withdraw fee does the exchange charge for this denomination - * @param fee_deposit what deposit fee does the exchange charge for this denomination - * @param fee_refresh what refresh fee does the exchange charge for this denomination - * @param fee_refund what refund fee does the exchange charge for this denomination + * @param fees fees for this denomination * @param master_priv private key to sign with * @param[out] master_sig where to write the signature */ @@ -2739,10 +2799,7 @@ TALER_exchange_offline_denom_validity_sign ( struct GNUNET_TIME_Timestamp stamp_expire_deposit, struct GNUNET_TIME_Timestamp stamp_expire_legal, const struct TALER_Amount *coin_value, - const struct TALER_Amount *fee_withdraw, - const struct TALER_Amount *fee_deposit, - const struct TALER_Amount *fee_refresh, - const struct TALER_Amount *fee_refund, + const struct TALER_DenomFeeSet *fees, const struct TALER_MasterPrivateKeyP *master_priv, struct TALER_MasterSignatureP *master_sig); @@ -2756,10 +2813,7 @@ TALER_exchange_offline_denom_validity_sign ( * @param stamp_expire_deposit how long does the exchange accept the deposit of coins with this key * @param stamp_expire_legal how long does the exchange preserve information for legal disputes with this key * @param coin_value what is the value of coins signed with this key - * @param fee_withdraw what withdraw fee does the exchange charge for this denomination - * @param fee_deposit what deposit fee does the exchange charge for this denomination - * @param fee_refresh what refresh fee does the exchange charge for this denomination - * @param fee_refund what refund fee does the exchange charge for this denomination + * @param fees fees for this denomination * @param master_pub public key to verify against * @param master_sig the signature the signature * @return #GNUNET_OK if the signature is valid @@ -2772,10 +2826,7 @@ TALER_exchange_offline_denom_validity_verify ( struct GNUNET_TIME_Timestamp stamp_expire_deposit, struct GNUNET_TIME_Timestamp stamp_expire_legal, const struct TALER_Amount *coin_value, - const struct TALER_Amount *fee_withdraw, - const struct TALER_Amount *fee_deposit, - const struct TALER_Amount *fee_refresh, - const struct TALER_Amount *fee_refund, + const struct TALER_DenomFeeSet *fees, const struct TALER_MasterPublicKeyP *master_pub, const struct TALER_MasterSignatureP *master_sig); @@ -2910,10 +2961,7 @@ TALER_exchange_secmod_cs_verify ( * @param stamp_expire_deposit how long does the exchange accept the deposit of coins with this key * @param stamp_expire_legal how long does the exchange preserve information for legal disputes with this key * @param coin_value what is the value of coins signed with this key - * @param fee_withdraw what withdraw fee does the exchange charge for this denomination - * @param fee_deposit what deposit fee does the exchange charge for this denomination - * @param fee_refresh what refresh fee does the exchange charge for this denomination - * @param fee_refund what refund fee does the exchange charge for this denomination + * @param fees fees the exchange charges for this denomination * @param auditor_priv private key to sign with * @param[out] auditor_sig where to write the signature */ @@ -2927,10 +2975,7 @@ TALER_auditor_denom_validity_sign ( struct GNUNET_TIME_Timestamp stamp_expire_deposit, struct GNUNET_TIME_Timestamp stamp_expire_legal, const struct TALER_Amount *coin_value, - const struct TALER_Amount *fee_withdraw, - const struct TALER_Amount *fee_deposit, - const struct TALER_Amount *fee_refresh, - const struct TALER_Amount *fee_refund, + const struct TALER_DenomFeeSet *fees, const struct TALER_AuditorPrivateKeyP *auditor_priv, struct TALER_AuditorSignatureP *auditor_sig); @@ -2946,10 +2991,7 @@ TALER_auditor_denom_validity_sign ( * @param stamp_expire_deposit how long does the exchange accept the deposit of coins with this key * @param stamp_expire_legal how long does the exchange preserve information for legal disputes with this key * @param coin_value what is the value of coins signed with this key - * @param fee_withdraw what withdraw fee does the exchange charge for this denomination - * @param fee_deposit what deposit fee does the exchange charge for this denomination - * @param fee_refresh what refresh fee does the exchange charge for this denomination - * @param fee_refund what refund fee does the exchange charge for this denomination + * @param fees fees the exchange charges for this denomination * @param auditor_pub public key to verify against * @param auditor_sig the signature the signature * @return #GNUNET_OK if the signature is valid @@ -2964,10 +3006,7 @@ TALER_auditor_denom_validity_verify ( struct GNUNET_TIME_Timestamp stamp_expire_deposit, struct GNUNET_TIME_Timestamp stamp_expire_legal, const struct TALER_Amount *coin_value, - const struct TALER_Amount *fee_withdraw, - const struct TALER_Amount *fee_deposit, - const struct TALER_Amount *fee_refresh, - const struct TALER_Amount *fee_refund, + const struct TALER_DenomFeeSet *fees, const struct TALER_AuditorPublicKeyP *auditor_pub, const struct TALER_AuditorSignatureP *auditor_sig); diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index fef09f721..df1d4da93 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -135,24 +135,9 @@ struct TALER_EXCHANGE_DenomPublicKey struct TALER_Amount value; /** - * The applicable fee for withdrawing a coin of this denomination - */ - struct TALER_Amount fee_withdraw; - - /** - * The applicable fee to spend a coin of this denomination + * The applicable fees for this denomination */ - struct TALER_Amount fee_deposit; - - /** - * The applicable fee to melt/refresh a coin of this denomination - */ - struct TALER_Amount fee_refresh; - - /** - * The applicable fee to refund a coin of this denomination - */ - struct TALER_Amount fee_refund; + struct TALER_DenomFeeSet fees; /** * Set to true if this denomination key has been @@ -1031,19 +1016,19 @@ void TALER_EXCHANGE_refund_cancel (struct TALER_EXCHANGE_RefundHandle *refund); -/* ********************* POST /csr *********************** */ +/* ********************* POST /csr-melt *********************** */ /** - * @brief A /csr Handle + * @brief A /csr-melt Handle */ -struct TALER_EXCHANGE_CsRHandle; +struct TALER_EXCHANGE_CsRMeltHandle; /** * Details about a response for a CS R request. */ -struct TALER_EXCHANGE_CsRResponse +struct TALER_EXCHANGE_CsRMeltResponse { /** * HTTP response data. @@ -1092,29 +1077,31 @@ struct TALER_EXCHANGE_CsRResponse * @param csrr response details */ typedef void -(*TALER_EXCHANGE_CsRCallback) (void *cls, - const struct TALER_EXCHANGE_CsRResponse *csrr); +(*TALER_EXCHANGE_CsRMeltCallback) ( + void *cls, + const struct TALER_EXCHANGE_CsRMeltResponse *csrr); /** - * Information we pass per coin to a /csr request. + * Information we pass per coin to a /csr-melt request. */ struct TALER_EXCHANGE_NonceKey { /** - * Which denomination key is the /csr request for? + * Which denomination key is the /csr-melt request for? */ const struct TALER_EXCHANGE_DenomPublicKey *pk; /** - * What is the client nonce for the request? + * What is number to derive the client nonce for the + * fresh coin? */ - struct TALER_CsNonce nonce; + uint32_t cnc_num; }; /** - * Get a CS R using a /csr request. + * Get a set of CS R values using a /csr-melt request. * * @param exchange the exchange handle; the exchange must be ready to operate * @param nks_len length of the @a nks array @@ -1125,23 +1112,117 @@ struct TALER_EXCHANGE_NonceKey * if the inputs are invalid (i.e. denomination key not with this exchange). * In this case, the callback is not called. */ -struct TALER_EXCHANGE_CsRHandle * -TALER_EXCHANGE_csr (struct TALER_EXCHANGE_Handle *exchange, - unsigned int nks_len, - struct TALER_EXCHANGE_NonceKey *nks, - TALER_EXCHANGE_CsRCallback res_cb, - void *res_cb_cls); +struct TALER_EXCHANGE_CsRMeltHandle * +TALER_EXCHANGE_csr_melt (struct TALER_EXCHANGE_Handle *exchange, + const struct TALER_RefreshMasterSecretP *rms, + unsigned int nks_len, + struct TALER_EXCHANGE_NonceKey *nks, + TALER_EXCHANGE_CsRMeltCallback res_cb, + void *res_cb_cls); + + +/** + * + * Cancel a CS R melt request. This function cannot be used + * on a request handle if a response is already served for it. + * + * @param csrh the withdraw handle + */ +void +TALER_EXCHANGE_csr_melt_cancel (struct TALER_EXCHANGE_CsRMeltHandle *csrh); + + +/* ********************* POST /csr-withdraw *********************** */ + + +/** + * @brief A /csr-withdraw Handle + */ +struct TALER_EXCHANGE_CsRWithdrawHandle; + + +/** + * Details about a response for a CS R request. + */ +struct TALER_EXCHANGE_CsRWithdrawResponse +{ + /** + * HTTP response data. + */ + struct TALER_EXCHANGE_HttpResponse hr; + + /** + * Details about the response. + */ + union + { + /** + * Details if the status is #MHD_HTTP_OK. + */ + struct + { + /** + * Values contributed by the exchange for the + * respective coin's withdraw operation. + */ + struct TALER_ExchangeWithdrawValues alg_values; + } success; + + /** + * Details if the status is #MHD_HTTP_GONE. + */ + struct + { + /* TODO: returning full details is not implemented */ + } gone; + + } details; +}; + + +/** + * Callbacks of this type are used to serve the result of submitting a + * CS R withdraw request to a exchange. + * + * @param cls closure + * @param csrr response details + */ +typedef void +(*TALER_EXCHANGE_CsRWithdrawCallback) ( + void *cls, + const struct TALER_EXCHANGE_CsRWithdrawResponse *csrr); + + +/** + * Get a CS R using a /csr-withdraw request. + * + * @param exchange the exchange handle; the exchange must be ready to operate + * @param dk Which denomination key is the /csr request for + * @param nonce client nonce for the request + * @param res_cb the callback to call when the final result for this request is available + * @param res_cb_cls closure for the above callback + * @return handle for the operation on success, NULL on error, i.e. + * if the inputs are invalid (i.e. denomination key not with this exchange). + * In this case, the callback is not called. + */ +struct TALER_EXCHANGE_CsRWithdrawHandle * +TALER_EXCHANGE_csr_withdraw (struct TALER_EXCHANGE_Handle *exchange, + const struct TALER_EXCHANGE_DenomPublicKey *pk, + const struct TALER_CsNonce *nonce, + TALER_EXCHANGE_CsRWithdrawCallback res_cb, + void *res_cb_cls); /** * - * Cancel a CS R request. This function cannot be used + * Cancel a CS R withdraw request. This function cannot be used * on a request handle if a response is already served for it. * * @param csrh the withdraw handle */ void -TALER_EXCHANGE_csr_cancel (struct TALER_EXCHANGE_CsRHandle *csrh); +TALER_EXCHANGE_csr_withdraw_cancel ( + struct TALER_EXCHANGE_CsRWithdrawHandle *csrh); /* ********************* GET /reserves/$RESERVE_PUB *********************** */ diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h index f0a6f8bd6..41231c984 100644 --- a/src/include/taler_exchangedb_plugin.h +++ b/src/include/taler_exchangedb_plugin.h @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2021 Taler Systems SA + Copyright (C) 2014-2022 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -208,10 +208,7 @@ struct TALER_EXCHANGEDB_TableData struct GNUNET_TIME_Timestamp expire_deposit; struct GNUNET_TIME_Timestamp expire_legal; struct TALER_Amount coin; - struct TALER_Amount fee_withdraw; - struct TALER_Amount fee_deposit; - struct TALER_Amount fee_refresh; - struct TALER_Amount fee_refund; + struct TALER_DenomFeeSet fees; } denominations; struct @@ -612,29 +609,10 @@ struct TALER_EXCHANGEDB_DenominationKeyMetaData struct TALER_Amount value; /** - * The fee the exchange charges when a coin of this type is withdrawn. - * (can be zero). + * The fees the exchange charges for operations with + * coins of this denomination. */ - struct TALER_Amount fee_withdraw; - - /** - * The fee the exchange charges when a coin of this type is deposited. - * (can be zero). - */ - struct TALER_Amount fee_deposit; - - /** - * The fee the exchange charges when a coin of this type is refreshed. - * (can be zero). - */ - struct TALER_Amount fee_refresh; - - /** - * The fee the exchange charges when a coin of this type is refunded. - * (can be zero). Note that refund fees are charged to the customer; - * if a refund is given, the deposit fee is also refunded. - */ - struct TALER_Amount fee_refund; + struct TALER_DenomFeeSet fees; /** * Age restriction for the denomination. (can be zero). If not zero, the bits @@ -827,6 +805,23 @@ struct TALER_EXCHANGEDB_Recoup }; +/** + * Public key to which a nonce is locked. + */ +union TALER_EXCHANGEDB_NonceLockTargetP +{ + /** + * Nonce is locked to this coin key. + */ + struct TALER_CoinSpendPublicKeyP coin; + + /** + * Nonce is locked to this reserve key. + */ + struct TALER_ReservePublicKeyP reserve; +}; + + /** * Information the exchange records about a recoup request * in a coin history. @@ -1702,6 +1697,33 @@ struct TALER_EXCHANGEDB_RefreshRevealedCoin }; +/** + * Information per Clause-Schnorr (CS) fresh coin to + * be persisted for idempotency during refreshes-reveal. + */ +struct TALER_EXCHANGEDB_CsRevealFreshCoinData +{ + /** + * Denomination of the fresh coin. + */ + struct TALER_DenominationHash new_denom_pub_hash; + + /** + * Blind signature of the fresh coin (possibly updated + * in case if a replay!). + */ + struct TALER_BlindedDenominationSignature bsig; + + /** + * Offset of the fresh coin in the reveal operation. + * (May not match the array offset as we may have + * a mixture of RSA and CS coins being created, and + * this request is only made for the CS subset). + */ + uint32_t coin_off; +}; + + /** * Types of operations that require KYC checks. */ @@ -2497,20 +2519,36 @@ struct TALER_EXCHANGEDB_Plugin uint64_t wire_reference); + /** + * Locate a nonce for use with a particular public key. + * + * @param cls the @e cls of this struct with the plugin-specific state + * @param nonce the nonce to be locked + * @param denom_pub_hash hash of the public key of the denomination + * @param target public key the nonce is to be locked to + * @return statement execution status + */ + enum GNUNET_DB_QueryStatus + (*lock_nonce)(void *cls, + const struct TALER_CsNonce *nonce, + const struct TALER_DenominationHash *denom_pub_hash, + const union TALER_EXCHANGEDB_NonceLockTargetP *target); + + /** * Locate the response for a withdraw request under a hash that uniquely * identifies the withdraw operation. Used to ensure idempotency of the * request. * * @param cls the @e cls of this struct with the plugin-specific state - * @param wih hash that uniquely identifies the withdraw operation + * @param bch hash that uniquely identifies the withdraw operation * @param[out] collectable corresponding collectable coin (blind signature) * if a coin is found * @return statement execution status */ enum GNUNET_DB_QueryStatus (*get_withdraw_info)(void *cls, - const struct TALER_WithdrawIdentificationHash *wih, + const struct TALER_BlindedCoinHash *bch, struct TALER_EXCHANGEDB_CollectableBlindcoin *collectable); @@ -2519,9 +2557,8 @@ struct TALER_EXCHANGEDB_Plugin * and possibly persisting the withdrawal details. * * @param cls the `struct PostgresClosure` with the plugin-specific state - * @param wih hash that uniquely identifies the withdraw operation - * @param[in,out] collectable corresponding collectable coin (blind signature) - * if a coin is found + * @param nonce client-contributed input for CS denominations that must be checked for idempotency, or NULL for non-CS withdrawals + * @param collectable corresponding collectable coin (blind signature) * @param now current time (rounded) * @param[out] found set to true if the reserve was found * @param[out] balance_ok set to true if the balance was sufficient @@ -2532,8 +2569,8 @@ struct TALER_EXCHANGEDB_Plugin enum GNUNET_DB_QueryStatus (*do_withdraw)( void *cls, - const struct TALER_WithdrawIdentificationHash *wih, - struct TALER_EXCHANGEDB_CollectableBlindcoin *collectable, + const struct TALER_CsNonce *nonce, + const struct TALER_EXCHANGEDB_CollectableBlindcoin *collectable, struct GNUNET_TIME_Timestamp now, bool *found, bool *balance_ok, @@ -2591,7 +2628,8 @@ struct TALER_EXCHANGEDB_Plugin * Perform melt operation, checking for sufficient balance * of the coin and possibly persisting the melt details. * - * @param cls the `struct PostgresClosure` with the plugin-specific state + * @param cls the plugin-specific state + * @param rms client-contributed input for CS denominations that must be checked for idempotency, or NULL for non-CS withdrawals * @param[in,out] refresh refresh operation details; the noreveal_index * is set in case the coin was already melted before * @param known_coin_id row of the coin in the known_coins table @@ -2602,12 +2640,35 @@ struct TALER_EXCHANGEDB_Plugin enum GNUNET_DB_QueryStatus (*do_melt)( void *cls, + const struct TALER_RefreshMasterSecretP *rms, struct TALER_EXCHANGEDB_Refresh *refresh, uint64_t known_coin_id, bool *zombie_required, bool *balance_ok); + /** + * Check if the given @a nonce was properly locked to the given @a old_coin_pub. If so, check if we already + * created CS signatures for the given @a nonce and @a new_denom_pub_hashes, + * and if so, return them in @a s_scalars. Otherwise, persist the + * signatures from @a s_scalars in the database. + * + * @param cls the plugin-specific state + * @param nonce the client-provided nonce where we must prevent reuse + * @param old_coin_pub public key the nonce was locked to + * @param num_fresh_coins array length, number of fresh coins revealed + * @param[in,out] crfcds array of data about the fresh coins, of length @a num_fresh_coins + * @return query execution status + */ + enum GNUNET_DB_QueryStatus + (*cs_refreshes_reveal)( + void *cls, + const struct TALER_CsNonce *nonce, + const struct TALER_CoinSpendPublicKeyP *old_coin_pub, + unsigned int num_fresh_coins, + struct TALER_EXCHANGEDB_CsRevealFreshCoinData *crfcds); + + /** * Perform refund operation, checking for sufficient deposits * of the coin and possibly persisting the refund details. @@ -3540,16 +3601,16 @@ struct TALER_EXCHANGEDB_Plugin * from given the hash of the blinded coin. * * @param cls closure - * @param wih hash identifying the withdraw operation + * @param bch hash identifying the withdraw operation * @param[out] reserve_pub set to information about the reserve (on success only) * @param[out] reserve_out_serial_id set to row of the @a h_blind_ev in reserves_out * @return transaction status code */ enum GNUNET_DB_QueryStatus - (*get_reserve_by_wih)(void *cls, - const struct TALER_WithdrawIdentificationHash *wih, - struct TALER_ReservePublicKeyP *reserve_pub, - uint64_t *reserve_out_serial_id); + (*get_reserve_by_h_blind)(void *cls, + const struct TALER_BlindedCoinHash *bch, + struct TALER_ReservePublicKeyP *reserve_pub, + uint64_t *reserve_out_serial_id); /** diff --git a/src/include/taler_json_lib.h b/src/include/taler_json_lib.h index e3e47222b..8a7e5cd8b 100644 --- a/src/include/taler_json_lib.h +++ b/src/include/taler_json_lib.h @@ -250,6 +250,35 @@ TALER_JSON_spec_amount_any_nbo (const char *name, struct TALER_AmountNBO *r_amount); +/** + * Generate specification to parse all fees for + * a denomination under a prefix @a pfx. + * + * @param pfx string prefix to use + * @param currency which currency to expect + * @param[out] dfs a `struct TALER_DenomFeeSet` to initialize + */ +#define TALER_JSON_SPEC_DENOM_FEES(pfx,currency,dfs) \ + TALER_JSON_spec_amount (pfx "_withdraw", (currency), &(dfs)->withdraw), \ + TALER_JSON_spec_amount (pfx "_deposit", (currency), &(dfs)->deposit), \ + TALER_JSON_spec_amount (pfx "_refresh", (currency), &(dfs)->refresh), \ + TALER_JSON_spec_amount (pfx "_refund", (currency), &(dfs)->refund) + + +/** + * Macro to pack all of a denominations' fees under + * a given @a pfx. + * + * @param pfx string prefix to use + * @param dfs a `struct TALER_DenomFeeSet` to pack + */ +#define TALER_JSON_PACK_DENOM_FEES(pfx, dfs) \ + TALER_JSON_pack_amount (pfx "_withdraw", &(dfs)->withdraw), \ + TALER_JSON_pack_amount (pfx "_deposit", &(dfs)->deposit), \ + TALER_JSON_pack_amount (pfx "_refresh", &(dfs)->refresh), \ + TALER_JSON_pack_amount (pfx "_refund", &(dfs)->refund) + + /** * Generate line in parser specification for denomination public key. * diff --git a/src/include/taler_signatures.h b/src/include/taler_signatures.h index e3d9a8939..8a799eaea 100644 --- a/src/include/taler_signatures.h +++ b/src/include/taler_signatures.h @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2021 Taler Systems SA + Copyright (C) 2014-2022 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -395,6 +395,7 @@ struct TALER_SigningKeyAnnouncementPS }; + /** * @brief Format used for to allow the wallet to authenticate * link data provided by the exchange. @@ -999,6 +1000,7 @@ struct TALER_MasterExtensionConfigurationPS struct TALER_ExtensionConfigHash h_config GNUNET_PACKED; }; + /** * @brief Information about a denomination key. Denomination keys * are used to sign coins of a certain value into existence. @@ -1063,29 +1065,9 @@ struct TALER_DenominationKeyValidityPS struct TALER_AmountNBO value; /** - * The fee the exchange charges when a coin of this type is withdrawn. - * (can be zero). - */ - struct TALER_AmountNBO fee_withdraw; - - /** - * The fee the exchange charges when a coin of this type is deposited. - * (can be zero). - */ - struct TALER_AmountNBO fee_deposit; - - /** - * The fee the exchange charges when a coin of this type is refreshed. - * (can be zero). - */ - struct TALER_AmountNBO fee_refresh; - - /** - * The fee the exchange charges when a coin of this type is refunded. - * (can be zero). Note that refund fees are charged to the customer; - * if a refund is given, the deposit fee is also refunded. + * Fees for the coin. */ - struct TALER_AmountNBO fee_refund; + struct TALER_DenomFeeSetNBOP fees; /** * Hash code of the denomination public key. (Used to avoid having @@ -1166,28 +1148,9 @@ struct TALER_ExchangeKeyValidityPS struct TALER_AmountNBO value; /** - * The fee the exchange charges when a coin of this type is withdrawn. - * (can be zero). - */ - struct TALER_AmountNBO fee_withdraw; - - /** - * The fee the exchange charges when a coin of this type is deposited. - * (can be zero). - */ - struct TALER_AmountNBO fee_deposit; - - /** - * The fee the exchange charges when a coin of this type is refreshed. - * (can be zero). - */ - struct TALER_AmountNBO fee_refresh; - - /** - * The fee the exchange charges when a coin of this type is refreshed. - * (can be zero). + * Fees for the coin. */ - struct TALER_AmountNBO fee_refund; + struct TALER_DenomFeeSetNBOP fees; /** * Hash code of the denomination public key. (Used to avoid having diff --git a/src/include/taler_util.h b/src/include/taler_util.h index b7b748698..1eba4e327 100644 --- a/src/include/taler_util.h +++ b/src/include/taler_util.h @@ -144,6 +144,39 @@ TALER_config_get_amount (const struct GNUNET_CONFIGURATION_Handle *cfg, struct TALER_Amount *denom); +/** + * Obtain denomination fee structure of a + * denomination from configuration file. All + * fee options must start with "fee_" and have + * names typical for the respective fees. + * + * @param cfg configuration to extract data from + * @param currency expected currency + * @param section section of the configuration to access + * @param[out] fees set to the denomination fees + * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + */ +enum GNUNET_GenericReturnValue +TALER_config_get_denom_fees (const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *currency, + const char *section, + struct TALER_DenomFeeSet *fees); + + +/** + * Check that all denominations in @a fees use + * @a currency + * + * @param currency desired currency + * @param fees fee set to check + * @return #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +TALER_denom_fee_check_currency ( + const char *currency, + const struct TALER_DenomFeeSet *fees); + + /** * Load our currency from the @a cfg (in section [taler] * the option "CURRENCY"). -- cgit v1.2.3