From 2c14d338704f4574055c4b5c51d8a79dd2e22345 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Tue, 21 Dec 2021 16:16:10 +0100 Subject: [PATCH] deduplicate melt signing logic, remove coin_pub from data being signed over --- src/auditor/taler-helper-auditor-coins.c | 20 +++------ src/include/taler_crypto_lib.h | 41 ++++++++++++++++++ src/include/taler_signatures.h | 7 --- src/lib/exchange_api_melt.c | 28 +++++------- src/util/wallet_signatures.c | 54 ++++++++++++++++++++++++ 5 files changed, 113 insertions(+), 37 deletions(-) diff --git a/src/auditor/taler-helper-auditor-coins.c b/src/auditor/taler-helper-auditor-coins.c index 393fc464b..16d030b7f 100644 --- a/src/auditor/taler-helper-auditor-coins.c +++ b/src/auditor/taler-helper-auditor-coins.c @@ -1287,23 +1287,17 @@ refresh_session_cb (void *cls, /* verify melt signature */ { - struct TALER_RefreshMeltCoinAffirmationPS rmc = { - .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_MELT), - .purpose.size = htonl (sizeof (rmc)), - .rc = *rc, - .melt_fee = issue->fee_refresh, - .coin_pub = *coin_pub - }; + const struct TALER_DenominationHash h_denom_pub; TALER_denom_pub_hash (denom_pub, &rmc.h_denom_pub); - TALER_amount_hton (&rmc.amount_with_fee, - amount_with_fee); if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_MELT, - &rmc, - &coin_sig->eddsa_signature, - &coin_pub->eddsa_pub)) + TALER_wallet_melt_verify (&rmc.amount_with_fee, + &issue->fee_refresh, + rc, + &h_denom_pub, + coin_pub, + coin_sig)) { TALER_ARL_report (report_bad_sig_losses, GNUNET_JSON_PACK ( diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h index 5895d1210..89e8697d6 100644 --- a/src/include/taler_crypto_lib.h +++ b/src/include/taler_crypto_lib.h @@ -1723,6 +1723,47 @@ TALER_wallet_deposit_verify ( const struct TALER_CoinSpendSignatureP *coin_sig); +/** + * Sign a melt request. + * + * @param amount the amount to be melted (with fee) + * @param melt_fee the melt fee we expect to pay + * @param rc refresh session we are committed to + * @param h_denom_pub hash of the coin denomination's public key + * @param coin_priv coin’s private key + * @param[out] coin_sig set to the signature made with purpose #TALER_SIGNATURE_WALLET_COIN_MELT + */ +void +TALER_wallet_melt_sign ( + const struct TALER_Amount *amount_with_fee, + const struct TALER_Amount *melt_fee, + const struct TALER_RefreshCommitmentP *rc, + const struct TALER_DenominationHash *h_denom_pub, + const struct TALER_CoinSpendPrivateKeyP *coin_priv, + struct TALER_CoinSpendSignatureP *coin_sig); + + +/** + * Verify a melt request. + * + * @param amount the amount to be melted (with fee) + * @param melt_fee the melt fee we expect to pay + * @param rc refresh session we are committed to + * @param h_denom_pub hash of the coin denomination's public key + * @param coin_pub coin’s public key + * @param coin_sig the signature made with purpose #TALER_SIGNATURE_WALLET_COIN_MELT + * @return #GNUNET_OK if the signature is valid + */ +enum GNUNET_GenericReturnValue +TALER_wallet_melt_verify ( + const struct TALER_Amount *amount_with_fee, + const struct TALER_Amount *melt_fee, + const struct TALER_RefreshCommitmentP *rc, + const struct TALER_DenominationHash *h_denom_pub, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_CoinSpendSignatureP *coin_sig); + + /** * Sign link data. * diff --git a/src/include/taler_signatures.h b/src/include/taler_signatures.h index 643aa80de..d3a3d02fc 100644 --- a/src/include/taler_signatures.h +++ b/src/include/taler_signatures.h @@ -728,13 +728,6 @@ struct TALER_RefreshMeltCoinAffirmationPS * session. */ struct TALER_AmountNBO melt_fee; - - /** - * The coin's public key. This is the value that must have been - * signed (blindly) by the Exchange. The deposit request is to be - * signed by the corresponding private key (using EdDSA). - */ - struct TALER_CoinSpendPublicKeyP coin_pub; }; diff --git a/src/lib/exchange_api_melt.c b/src/lib/exchange_api_melt.c index 6ef9f4cbc..ab20e6fc1 100644 --- a/src/lib/exchange_api_melt.c +++ b/src/lib/exchange_api_melt.c @@ -464,10 +464,8 @@ TALER_EXCHANGE_melt (struct TALER_EXCHANGE_Handle *exchange, struct MeltData *md; struct TALER_CoinSpendSignatureP confirm_sig; char arg_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2 + 32]; - struct TALER_RefreshMeltCoinAffirmationPS melt = { - .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_MELT), - .purpose.size = htonl (sizeof (melt)), - }; + struct TALER_DenominationHash h_denom_pub; + struct TALER_CoinSpendPublicKeyP coin_pub; GNUNET_assert (GNUNET_YES == TEAH_handle_is_ready (exchange)); @@ -478,21 +476,17 @@ TALER_EXCHANGE_melt (struct TALER_EXCHANGE_Handle *exchange, GNUNET_break (0); return NULL; } - melt.rc = md->rc; - TALER_amount_hton (&melt.amount_with_fee, - &md->melted_coin.melt_amount_with_fee); - TALER_amount_hton (&melt.melt_fee, - &md->melted_coin.fee_melt); - GNUNET_CRYPTO_eddsa_key_get_public (&md->melted_coin.coin_priv.eddsa_priv, - &melt.coin_pub.eddsa_pub); TALER_denom_pub_hash (&md->melted_coin.pub_key, - &melt.h_denom_pub); - GNUNET_CRYPTO_eddsa_sign (&md->melted_coin.coin_priv.eddsa_priv, - &melt, - &confirm_sig.eddsa_signature); + &h_denom_pub); + TALER_wallet_melt_sign (&md->melted_coin.melt_amount_with_fee, + &md->melted_coin.fee_melt, + &md->rc, + &h_denom_pub, + &md->melted_coin.coin_priv, + &confirm_sig); + GNUNET_CRYPTO_eddsa_key_get_public (&md->melted_coin.coin_priv.eddsa_priv, + &coin_pub.eddsa_pub); melt_obj = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_data_auto ("coin_pub", - &melt.coin_pub), GNUNET_JSON_pack_data_auto ("denom_pub_hash", &melt.h_denom_pub), TALER_JSON_pack_denom_sig ("denom_sig", diff --git a/src/util/wallet_signatures.c b/src/util/wallet_signatures.c index 81ce9cc5f..f686b765c 100644 --- a/src/util/wallet_signatures.c +++ b/src/util/wallet_signatures.c @@ -202,4 +202,58 @@ TALER_wallet_recoup_sign ( } +void +TALER_wallet_melt_sign ( + const struct TALER_Amount *amount_with_fee, + const struct TALER_Amount *melt_fee, + const struct TALER_RefreshCommitmentP *rc, + const struct TALER_DenominationHash *h_denom_pub, + const struct TALER_CoinSpendPrivateKeyP *coin_priv, + struct TALER_CoinSpendSignatureP *coin_sig) +{ + struct TALER_RefreshMeltCoinAffirmationPS melt = { + .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_MELT), + .purpose.size = htonl (sizeof (melt)), + .rc = *rc, + .h_denom_pub = *h_denom_pub + }; + + TALER_amount_hton (&melt.amount_with_fee, + amount_with_fee); + TALER_amount_hton (&melt.melt_fee, + melt_fee); + GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv, + &melt, + &coin_sig->eddsa_signature); +} + + +enum GNUNET_GenericReturnValue +TALER_wallet_melt_verify ( + const struct TALER_Amount *amount_with_fee, + const struct TALER_Amount *melt_fee, + const struct TALER_RefreshCommitmentP *rc, + const struct TALER_DenominationHash *h_denom_pub, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_CoinSpendSignatureP *coin_sig) +{ + struct TALER_RefreshMeltCoinAffirmationPS melt = { + .purpose.size = htonl (sizeof (melt)), + .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_MELT), + .rc = *rc, + .h_denom_pub = *h_denom_pub + }; + + TALER_amount_hton (&melt.amount_with_fee, + amount_with_fee); + TALER_amount_hton (&melt.melt_fee, + melt_fee); + return GNUNET_CRYPTO_eddsa_verify ( + TALER_SIGNATURE_WALLET_COIN_MELT, + &melt, + &coin_sig->eddsa_signature, + &coin_pub->eddsa_pub); +} + + /* end of wallet_signatures.c */