From 8175fdfa0f47e74e239190e809eff4dda5565a76 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 6 Nov 2021 16:52:14 +0100 Subject: [PATCH] introduce TALER_wallet_deposit_verify --- src/auditor/taler-helper-auditor-coins.c | 36 +++---- src/exchange/taler-exchange-httpd_deposit.c | 48 ++++------ src/exchange/taler-exchange-httpd_responses.c | 36 +++---- src/include/taler_crypto_lib.h | 62 +++++++++++++ src/lib/exchange_api_common.c | 51 +++++----- src/lib/exchange_api_deposit.c | 93 ++++--------------- src/lib/exchange_api_refund.c | 58 +++++++----- src/testing/testing_api_cmd_deposit.c | 22 ++--- src/util/wallet_signatures.c | 85 +++++++++++++++++ 9 files changed, 287 insertions(+), 204 deletions(-) diff --git a/src/auditor/taler-helper-auditor-coins.c b/src/auditor/taler-helper-auditor-coins.c index b086cec4b..56683e58a 100644 --- a/src/auditor/taler-helper-auditor-coins.c +++ b/src/auditor/taler-helper-auditor-coins.c @@ -1619,32 +1619,32 @@ deposit_cb (void *cls, /* Verify deposit signature */ { - struct TALER_DepositRequestPS dr = { - .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT), - .purpose.size = htonl (sizeof (dr)), - .h_contract_terms = deposit->h_contract_terms, - .wallet_timestamp = GNUNET_TIME_absolute_hton (deposit->timestamp), - .refund_deadline = GNUNET_TIME_absolute_hton (deposit->refund_deadline), - .deposit_fee = issue->fee_deposit, - .merchant = deposit->merchant_pub, - .coin_pub = deposit->coin.coin_pub - }; + struct TALER_MerchantWireHash h_wire; + struct TALER_DenominationHash h_denom_pub; + struct TALER_Amount deposit_fee; TALER_denom_pub_hash (denom_pub, - &dr.h_denom_pub); + &h_denom_pub); TALER_merchant_wire_signature_hash (deposit->receiver_wire_account, &deposit->wire_salt, - &dr.h_wire); - TALER_amount_hton (&dr.amount_with_fee, - &deposit->amount_with_fee); + &h_wire); + TALER_amount_ntoh (&deposit_fee, + &issue->fee_deposit); /* NOTE: This is one of the operations we might eventually want to do in parallel in the background to improve auditor performance! */ if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_DEPOSIT, - &dr, - &deposit->csig.eddsa_signature, - &deposit->coin.coin_pub.eddsa_pub)) + TALER_wallet_deposit_verify (&deposit->amount_with_fee, + &deposit_fee, + &h_wire, + &deposit->h_contract_terms, + NULL /* h_extensions! */, + &h_denom_pub, + deposit->timestamp, + &deposit->merchant_pub, + deposit->refund_deadline, + &deposit->coin.coin_pub, + &deposit->csig)) { TALER_ARL_report (report_bad_sig_losses, GNUNET_JSON_PACK ( diff --git a/src/exchange/taler-exchange-httpd_deposit.c b/src/exchange/taler-exchange-httpd_deposit.c index 8f0ac8218..323a77b55 100644 --- a/src/exchange/taler-exchange-httpd_deposit.c +++ b/src/exchange/taler-exchange-httpd_deposit.c @@ -510,37 +510,25 @@ TEH_handler_deposit (struct MHD_Connection *connection, NULL); } - /* check deposit signature */ + if (GNUNET_OK != + TALER_wallet_deposit_verify (&deposit.amount_with_fee, + &deposit.deposit_fee, + &dc.h_wire, + &deposit.h_contract_terms, + NULL /* h_extensions! */, + &deposit.coin.denom_pub_hash, + deposit.timestamp, + &deposit.merchant_pub, + deposit.refund_deadline, + &deposit.coin.coin_pub, + &deposit.csig)) { - struct TALER_DepositRequestPS dr = { - .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT), - .purpose.size = htonl (sizeof (dr)), - .h_contract_terms = deposit.h_contract_terms, - .h_wire = dc.h_wire, - .h_denom_pub = deposit.coin.denom_pub_hash, - .wallet_timestamp = GNUNET_TIME_absolute_hton (deposit.timestamp), - .refund_deadline = GNUNET_TIME_absolute_hton (deposit.refund_deadline), - .merchant = deposit.merchant_pub, - .coin_pub = deposit.coin.coin_pub - }; - - TALER_amount_hton (&dr.amount_with_fee, - &deposit.amount_with_fee); - TALER_amount_hton (&dr.deposit_fee, - &deposit.deposit_fee); - if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_DEPOSIT, - &dr, - &deposit.csig.eddsa_signature, - &deposit.coin.coin_pub.eddsa_pub)) - { - TALER_LOG_WARNING ("Invalid signature on /deposit request\n"); - GNUNET_JSON_parse_free (spec); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_UNAUTHORIZED, - TALER_EC_EXCHANGE_DEPOSIT_COIN_SIGNATURE_INVALID, - NULL); - } + TALER_LOG_WARNING ("Invalid signature on /deposit request\n"); + GNUNET_JSON_parse_free (spec); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_UNAUTHORIZED, + TALER_EC_EXCHANGE_DEPOSIT_COIN_SIGNATURE_INVALID, + NULL); } /* execute transaction */ diff --git a/src/exchange/taler-exchange-httpd_responses.c b/src/exchange/taler-exchange-httpd_responses.c index 6dd204c6d..cb1179d6d 100644 --- a/src/exchange/taler-exchange-httpd_responses.c +++ b/src/exchange/taler-exchange-httpd_responses.c @@ -61,33 +61,25 @@ TEH_RESPONSE_compile_transaction_history ( { const struct TALER_EXCHANGEDB_DepositListEntry *deposit = pos->details.deposit; - struct TALER_DepositRequestPS dr = { - .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT), - .purpose.size = htonl (sizeof (dr)), - .h_contract_terms = deposit->h_contract_terms, - .h_denom_pub = deposit->h_denom_pub, - .wallet_timestamp = GNUNET_TIME_absolute_hton (deposit->timestamp), - .refund_deadline = GNUNET_TIME_absolute_hton ( - deposit->refund_deadline), - .merchant = deposit->merchant_pub, - .coin_pub = *coin_pub - }; + struct TALER_MerchantWireHash h_wire; TALER_merchant_wire_signature_hash (deposit->receiver_wire_account, &deposit->wire_salt, - &dr.h_wire); - - TALER_amount_hton (&dr.amount_with_fee, - &deposit->amount_with_fee); - TALER_amount_hton (&dr.deposit_fee, - &deposit->deposit_fee); + &h_wire); #if ENABLE_SANITY_CHECKS /* internal sanity check before we hand out a bogus sig... */ if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_DEPOSIT, - &dr, - &deposit->csig.eddsa_signature, - &coin_pub->eddsa_pub)) + TALER_wallet_deposit_verify (&deposit->amount_with_fee, + &deposit->deposit_fee, + &h_wire, + &deposit->h_contract_terms, + NULL /* h_extensions! */, + &deposit->h_denom_pub, + deposit->timestamp, + &deposit->merchant_pub, + deposit->refund_deadline, + coin_pub, + &deposit->csig)) { GNUNET_break (0); json_decref (history); @@ -114,7 +106,7 @@ TEH_RESPONSE_compile_transaction_history ( GNUNET_JSON_pack_data_auto ("h_contract_terms", &deposit->h_contract_terms), GNUNET_JSON_pack_data_auto ("h_wire", - &dr.h_wire), + &h_wire), GNUNET_JSON_pack_data_auto ("h_denom_pub", &deposit->h_denom_pub), GNUNET_JSON_pack_data_auto ("coin_sig", diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h index 6bb4a50e2..881e368ee 100644 --- a/src/include/taler_crypto_lib.h +++ b/src/include/taler_crypto_lib.h @@ -1549,6 +1549,68 @@ TALER_CRYPTO_helper_esign_disconnect ( /* ********************* wallet signing ************************** */ + +/** + * Sign a deposit permission. Function for wallets. + * + * @param amount the amount to be deposited + * @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_extensions hash over the extensions + * @param h_denom_pub hash of the coin denomination's public key + * @param coin_priv coin’s private key + * @param wallet_timestamp timestamp when the contract was finalized, must not be too far in the future + * @param merchant_pub the public key of the merchant (used to identify the merchant for refund requests) + * @param refund_deadline date until which the merchant can issue a refund to the customer via the exchange (can be zero if refunds are not allowed); must not be after the @a wire_deadline + * @param[out] coin_sig set to the signature made with purpose #TALER_SIGNATURE_WALLET_COIN_DEPOSIT + */ +void +TALER_wallet_deposit_sign ( + const struct TALER_Amount *amount, + const struct TALER_Amount *deposit_fee, + const struct TALER_MerchantWireHash *h_wire, + const struct TALER_PrivateContractHash *h_contract_terms, + const struct TALER_ExtensionContractHash *h_extensions, + const struct TALER_DenominationHash *h_denom_pub, + struct GNUNET_TIME_Absolute wallet_timestamp, + const struct TALER_MerchantPublicKeyP *merchant_pub, + struct GNUNET_TIME_Absolute refund_deadline, + const struct TALER_CoinSpendPrivateKeyP *coin_priv, + struct TALER_CoinSpendSignatureP *coin_sig); + + +/** + * Verify a deposit permission. + * + * @param amount the amount to be deposited + * @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_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 + * @param merchant_pub the public key of the merchant (used to identify the merchant for refund requests) + * @param refund_deadline date until which the merchant can issue a refund to the customer via the exchange (can be zero if refunds are not allowed); must not be after the @a wire_deadline + * @param coin_pub coin’s public key + * @param coin_sig the signature made with purpose #TALER_SIGNATURE_WALLET_COIN_DEPOSIT + * @return #GNUNET_OK if the signature is valid + */ +enum GNUNET_GenericReturnValue +TALER_wallet_deposit_verify ( + const struct TALER_Amount *amount, + const struct TALER_Amount *deposit_fee, + const struct TALER_MerchantWireHash *h_wire, + const struct TALER_PrivateContractHash *h_contract_terms, + const struct TALER_ExtensionContractHash *h_extensions, + const struct TALER_DenominationHash *h_denom_pub, + struct GNUNET_TIME_Absolute wallet_timestamp, + const struct TALER_MerchantPublicKeyP *merchant_pub, + struct GNUNET_TIME_Absolute refund_deadline, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_CoinSpendSignatureP *coin_sig); + + /** * Sign link data. * diff --git a/src/lib/exchange_api_common.c b/src/lib/exchange_api_common.c index 4da7e33e8..900c871d2 100644 --- a/src/lib/exchange_api_common.c +++ b/src/lib/exchange_api_common.c @@ -492,30 +492,31 @@ TALER_EXCHANGE_verify_coin_history ( if (0 == strcasecmp (type, "DEPOSIT")) { - struct TALER_DepositRequestPS dr = { - .purpose.size = htonl (sizeof (dr)), - .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT), - .coin_pub = *coin_pub - }; + struct TALER_MerchantWireHash h_wire; + struct TALER_PrivateContractHash h_contract_terms; + // struct TALER_ExtensionContractHash h_extensions; // FIXME! + struct GNUNET_TIME_Absolute wallet_timestamp; + struct TALER_MerchantPublicKeyP merchant_pub; + struct GNUNET_TIME_Absolute refund_deadline = {0}; struct TALER_CoinSpendSignatureP sig; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("coin_sig", &sig), GNUNET_JSON_spec_fixed_auto ("h_contract_terms", - &dr.h_contract_terms), + &h_contract_terms), GNUNET_JSON_spec_fixed_auto ("h_wire", - &dr.h_wire), + &h_wire), GNUNET_JSON_spec_fixed_auto ("h_denom_pub", - &dr.h_denom_pub), - TALER_JSON_spec_absolute_time_nbo ("timestamp", - &dr.wallet_timestamp), + h_denom_pub), + TALER_JSON_spec_absolute_time ("timestamp", + &wallet_timestamp), GNUNET_JSON_spec_mark_optional ( - TALER_JSON_spec_absolute_time_nbo ("refund_deadline", - &dr.refund_deadline)), - TALER_JSON_spec_amount_any_nbo ("deposit_fee", - &dr.deposit_fee), + TALER_JSON_spec_absolute_time ("refund_deadline", + &refund_deadline)), + TALER_JSON_spec_amount_any ("deposit_fee", + &fee), GNUNET_JSON_spec_fixed_auto ("merchant_pub", - &dr.merchant), + &merchant_pub), GNUNET_JSON_spec_end () }; @@ -527,23 +528,25 @@ TALER_EXCHANGE_verify_coin_history ( GNUNET_break_op (0); return GNUNET_SYSERR; } - TALER_amount_hton (&dr.amount_with_fee, - &amount); if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_DEPOSIT, - &dr, - &sig.eddsa_signature, - &coin_pub->eddsa_pub)) + TALER_wallet_deposit_verify (&amount, + &fee, + &h_wire, + &h_contract_terms, + NULL /* h_extensions! */, + h_denom_pub, + wallet_timestamp, + &merchant_pub, + refund_deadline, + coin_pub, + &sig)) { GNUNET_break_op (0); return GNUNET_SYSERR; } - *h_denom_pub = dr.h_denom_pub; if (NULL != dk) { /* check that deposit fee matches our expectations from /keys! */ - TALER_amount_ntoh (&fee, - &dr.deposit_fee); if ( (GNUNET_YES != TALER_amount_cmp_currency (&fee, &dk->fee_deposit)) || diff --git a/src/lib/exchange_api_deposit.c b/src/lib/exchange_api_deposit.c index 8abb73518..188c17f18 100644 --- a/src/lib/exchange_api_deposit.c +++ b/src/lib/exchange_api_deposit.c @@ -431,39 +431,26 @@ verify_signatures (const struct TALER_EXCHANGE_DenomPublicKey *dki, struct GNUNET_TIME_Absolute refund_deadline, const struct TALER_CoinSpendSignatureP *coin_sig) { + if (GNUNET_OK != + TALER_wallet_deposit_verify (amount, + &dki->fee_deposit, + h_wire, + h_contract_terms, + NULL /* FIXME: h_extensions! */, + denom_pub_hash, + timestamp, + merchant_pub, + refund_deadline, + coin_pub, + coin_sig)) { - struct TALER_DepositRequestPS dr = { - .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT), - .purpose.size = htonl (sizeof (dr)), - .h_contract_terms = *h_contract_terms, - .h_wire = *h_wire, - .h_denom_pub = *denom_pub_hash, - .wallet_timestamp = GNUNET_TIME_absolute_hton (timestamp), - .refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline), - .merchant = *merchant_pub, - .coin_pub = *coin_pub - }; - - TALER_amount_hton (&dr.amount_with_fee, - amount); - TALER_amount_hton (&dr.deposit_fee, - &dki->fee_deposit); - if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_DEPOSIT, - &dr, - &coin_sig->eddsa_signature, - &coin_pub->eddsa_pub)) - { - GNUNET_break_op (0); - TALER_LOG_WARNING ("Invalid coin signature on /deposit request!\n"); - { - TALER_LOG_DEBUG ("... amount_with_fee was %s\n", - TALER_amount2s (amount)); - TALER_LOG_DEBUG ("... deposit_fee was %s\n", - TALER_amount2s (&dki->fee_deposit)); - } - return GNUNET_SYSERR; - } + GNUNET_break_op (0); + TALER_LOG_WARNING ("Invalid coin signature on /deposit request!\n"); + TALER_LOG_DEBUG ("... amount_with_fee was %s\n", + TALER_amount2s (amount)); + TALER_LOG_DEBUG ("... deposit_fee was %s\n", + TALER_amount2s (&dki->fee_deposit)); + return GNUNET_SYSERR; } /* check coin signature */ @@ -496,48 +483,6 @@ verify_signatures (const struct TALER_EXCHANGE_DenomPublicKey *dki, } -void -TALER_EXCHANGE_deposit_permission_sign ( - const struct TALER_Amount *amount, - const struct TALER_Amount *deposit_fee, - const struct TALER_MerchantWireHash *h_wire, - const struct TALER_PrivateContractHash *h_contract_terms, - const struct TALER_ExtensionContractHash *h_extensions, - const struct TALER_DenominationHash *h_denom_pub, - const struct TALER_CoinSpendPrivateKeyP *coin_priv, - struct GNUNET_TIME_Absolute wallet_timestamp, - const struct TALER_MerchantPublicKeyP *merchant_pub, - struct GNUNET_TIME_Absolute refund_deadline, - struct TALER_CoinSpendSignatureP *coin_sig) -{ - struct TALER_DepositRequestPS dr = { - .purpose.size = htonl (sizeof (dr)), - .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT), - .h_contract_terms = *h_contract_terms, - .h_wire = *h_wire, - .h_denom_pub = *h_denom_pub, - .wallet_timestamp = GNUNET_TIME_absolute_hton (wallet_timestamp), - .refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline), - .merchant = *merchant_pub - }; - - // FIXME: sign also over h_extensions! - GNUNET_assert (GNUNET_OK == - GNUNET_TIME_round_abs (&wallet_timestamp)); - GNUNET_assert (GNUNET_OK == - GNUNET_TIME_round_abs (&refund_deadline)); - GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv->eddsa_priv, - &dr.coin_pub.eddsa_pub); - TALER_amount_hton (&dr.amount_with_fee, - amount); - TALER_amount_hton (&dr.deposit_fee, - deposit_fee); - GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv, - &dr, - &coin_sig->eddsa_signature); -} - - struct TALER_EXCHANGE_DepositHandle * TALER_EXCHANGE_deposit ( struct TALER_EXCHANGE_Handle *exchange, diff --git a/src/lib/exchange_api_refund.c b/src/lib/exchange_api_refund.c index a73f19fc9..1362a9c26 100644 --- a/src/lib/exchange_api_refund.c +++ b/src/lib/exchange_api_refund.c @@ -87,7 +87,7 @@ struct TALER_EXCHANGE_RefundHandle * @param[out] exchange_sig set to the exchange's signature * @return #GNUNET_OK if the signature is valid, #GNUNET_SYSERR if not */ -static int +static enum GNUNET_GenericReturnValue verify_refund_signature_ok (struct TALER_EXCHANGE_RefundHandle *rh, const json_t *json, struct TALER_ExchangePublicKeyP *exchange_pub, @@ -138,7 +138,7 @@ verify_refund_signature_ok (struct TALER_EXCHANGE_RefundHandle *rh, * @param json json reply with the coin transaction history * @return #GNUNET_OK if the signature is valid, #GNUNET_SYSERR if not */ -static int +static enum GNUNET_GenericReturnValue verify_conflict_history_ok (struct TALER_EXCHANGE_RefundHandle *rh, const json_t *json) { @@ -196,29 +196,32 @@ verify_conflict_history_ok (struct TALER_EXCHANGE_RefundHandle *rh, if (0 == strcasecmp (type, "DEPOSIT")) { - struct TALER_DepositRequestPS dr = { - .purpose.size = htonl (sizeof (dr)), - .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT), - .coin_pub = rh->depconf.coin_pub - }; + struct TALER_Amount deposit_fee; + struct TALER_MerchantWireHash h_wire; + struct TALER_PrivateContractHash h_contract_terms; + // struct TALER_ExtensionContractHash h_extensions; // FIXME! + struct TALER_DenominationHash h_denom_pub; + struct GNUNET_TIME_Absolute wallet_timestamp; + struct TALER_MerchantPublicKeyP merchant_pub; + struct GNUNET_TIME_Absolute refund_deadline; struct TALER_CoinSpendSignatureP sig; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("coin_sig", &sig), GNUNET_JSON_spec_fixed_auto ("h_contract_terms", - &dr.h_contract_terms), + &h_contract_terms), GNUNET_JSON_spec_fixed_auto ("h_wire", - &dr.h_wire), + &h_wire), GNUNET_JSON_spec_fixed_auto ("h_denom_pub", - &dr.h_denom_pub), - TALER_JSON_spec_absolute_time_nbo ("timestamp", - &dr.wallet_timestamp), - TALER_JSON_spec_absolute_time_nbo ("refund_deadline", - &dr.refund_deadline), - TALER_JSON_spec_amount_any_nbo ("deposit_fee", - &dr.deposit_fee), + &h_denom_pub), + TALER_JSON_spec_absolute_time ("timestamp", + &wallet_timestamp), + TALER_JSON_spec_absolute_time ("refund_deadline", + &refund_deadline), + TALER_JSON_spec_amount_any ("deposit_fee", + &deposit_fee), GNUNET_JSON_spec_fixed_auto ("merchant_pub", - &dr.merchant), + &merchant_pub), GNUNET_JSON_spec_end () }; @@ -230,21 +233,26 @@ verify_conflict_history_ok (struct TALER_EXCHANGE_RefundHandle *rh, GNUNET_break_op (0); return GNUNET_SYSERR; } - TALER_amount_hton (&dr.amount_with_fee, - &amount); if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_DEPOSIT, - &dr, - &sig.eddsa_signature, - &rh->depconf.coin_pub.eddsa_pub)) + TALER_wallet_deposit_verify (&amount, + &deposit_fee, + &h_wire, + &h_contract_terms, + NULL /* h_extensions! */, + &h_denom_pub, + wallet_timestamp, + &merchant_pub, + refund_deadline, + &rh->depconf.coin_pub, + &sig)) { GNUNET_break_op (0); return GNUNET_SYSERR; } if ( (0 != GNUNET_memcmp (&rh->depconf.h_contract_terms, - &dr.h_contract_terms)) || + &h_contract_terms)) || (0 != GNUNET_memcmp (&rh->depconf.merchant, - &dr.merchant)) ) + &merchant_pub)) ) { /* deposit information is about a different merchant/contract */ GNUNET_break_op (0); diff --git a/src/testing/testing_api_cmd_deposit.c b/src/testing/testing_api_cmd_deposit.c index de04df244..9d2e15b79 100644 --- a/src/testing/testing_api_cmd_deposit.c +++ b/src/testing/testing_api_cmd_deposit.c @@ -420,17 +420,17 @@ deposit_run (void *cls, GNUNET_assert (GNUNET_OK == TALER_JSON_merchant_wire_signature_hash (ds->wire_details, &h_wire)); - TALER_EXCHANGE_deposit_permission_sign (&ds->amount, - &denom_pub->fee_deposit, - &h_wire, - &h_contract_terms, - NULL, /* FIXME: extension hash! */ - &denom_pub->h_key, - coin_priv, - ds->wallet_timestamp, - &merchant_pub, - ds->refund_deadline, - &coin_sig); + TALER_wallet_deposit_sign (&ds->amount, + &denom_pub->fee_deposit, + &h_wire, + &h_contract_terms, + NULL, /* FIXME: extension hash! */ + &denom_pub->h_key, + ds->wallet_timestamp, + &merchant_pub, + ds->refund_deadline, + coin_priv, + &coin_sig); } ds->dh = TALER_EXCHANGE_deposit (is->exchange, &ds->amount, diff --git a/src/util/wallet_signatures.c b/src/util/wallet_signatures.c index 71a942d57..f6aa144d6 100644 --- a/src/util/wallet_signatures.c +++ b/src/util/wallet_signatures.c @@ -23,6 +23,91 @@ #include "taler_signatures.h" +void +TALER_wallet_deposit_sign ( + const struct TALER_Amount *amount, + const struct TALER_Amount *deposit_fee, + const struct TALER_MerchantWireHash *h_wire, + const struct TALER_PrivateContractHash *h_contract_terms, + const struct TALER_ExtensionContractHash *h_extensions, + const struct TALER_DenominationHash *h_denom_pub, + struct GNUNET_TIME_Absolute wallet_timestamp, + const struct TALER_MerchantPublicKeyP *merchant_pub, + struct GNUNET_TIME_Absolute refund_deadline, + const struct TALER_CoinSpendPrivateKeyP *coin_priv, + struct TALER_CoinSpendSignatureP *coin_sig) +{ + struct TALER_DepositRequestPS dr = { + .purpose.size = htonl (sizeof (dr)), + .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT), + .h_contract_terms = *h_contract_terms, + .h_wire = *h_wire, + .h_denom_pub = *h_denom_pub, + .wallet_timestamp = GNUNET_TIME_absolute_hton (wallet_timestamp), + .refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline), + .merchant = *merchant_pub + }; + + // FIXME: sign also over h_extensions! + GNUNET_assert (GNUNET_OK == + GNUNET_TIME_round_abs (&wallet_timestamp)); + GNUNET_assert (GNUNET_OK == + GNUNET_TIME_round_abs (&refund_deadline)); + GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv->eddsa_priv, + &dr.coin_pub.eddsa_pub); + TALER_amount_hton (&dr.amount_with_fee, + amount); + TALER_amount_hton (&dr.deposit_fee, + deposit_fee); + GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv, + &dr, + &coin_sig->eddsa_signature); +} + + +enum GNUNET_GenericReturnValue +TALER_wallet_deposit_verify ( + const struct TALER_Amount *amount, + const struct TALER_Amount *deposit_fee, + const struct TALER_MerchantWireHash *h_wire, + const struct TALER_PrivateContractHash *h_contract_terms, + const struct TALER_ExtensionContractHash *h_extensions, + const struct TALER_DenominationHash *h_denom_pub, + struct GNUNET_TIME_Absolute wallet_timestamp, + const struct TALER_MerchantPublicKeyP *merchant_pub, + struct GNUNET_TIME_Absolute refund_deadline, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_CoinSpendSignatureP *coin_sig) +{ + struct TALER_DepositRequestPS dr = { + .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT), + .purpose.size = htonl (sizeof (dr)), + .h_contract_terms = *h_contract_terms, + .h_wire = *h_wire, + .h_denom_pub = *h_denom_pub, + .wallet_timestamp = GNUNET_TIME_absolute_hton (wallet_timestamp), + .refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline), + .merchant = *merchant_pub, + .coin_pub = *coin_pub + }; + + TALER_amount_hton (&dr.amount_with_fee, + amount); + TALER_amount_hton (&dr.deposit_fee, + deposit_fee); + if (GNUNET_OK != + GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_DEPOSIT, + &dr, + &coin_sig->eddsa_signature, + &coin_pub->eddsa_pub)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + return GNUNET_OK; +} + + void TALER_wallet_link_sign (const struct TALER_DenominationHash *h_denom_pub, const struct TALER_TransferPublicKeyP *transfer_pub,