From c1b43de5b4b5a1b4512c6e1a6f87b830df240fc9 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Fri, 29 Jul 2022 09:21:38 +0200 Subject: [PATCH] add offline signature to drain profits (#4960) --- contrib/gana | 2 +- src/include/taler_crypto_lib.h | 49 +++++++++++++++++ src/include/taler_exchangedb_lib.h | 2 +- src/util/offline_signatures.c | 84 ++++++++++++++++++++++++++++++ 4 files changed, 135 insertions(+), 2 deletions(-) diff --git a/contrib/gana b/contrib/gana index 7bfe1654e..f4ec586e0 160000 --- a/contrib/gana +++ b/contrib/gana @@ -1 +1 @@ -Subproject commit 7bfe1654eeab7e7eacb4f6eb45ad52ffe4511c4d +Subproject commit f4ec586e0fc4c067fbc9e14b21d66f2573717c1e diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h index 1a0fb72e6..503cb13c2 100644 --- a/src/include/taler_crypto_lib.h +++ b/src/include/taler_crypto_lib.h @@ -4546,6 +4546,55 @@ TALER_exchange_offline_partner_details_verify ( const struct TALER_MasterSignatureP *master_sig); +/** + * Create offline signature about wiring profits to a + * regular non-escrowed account of the exchange. + * + * @param wtid (random) wire transfer ID to be used + * @param date when was the profit drain approved (not exact time of execution) + * @param amount how much should be wired + * @param account_section configuration section of the + * exchange specifying the account to be debited + * @param payto_uri target account to be credited + * @param master_priv private key to sign with + * @param[out] master_sig where to write the signature + */ +void +TALER_exchange_offline_profit_drain_sign ( + const struct TALER_WireTransferIdentifierRawP *wtid, + struct GNUNET_TIME_Timestamp date, + const struct TALER_Amount *amount, + const char *account_section, + const char *payto_uri, + const struct TALER_MasterPrivateKeyP *master_priv, + struct TALER_MasterSignatureP *master_sig); + + +/** + * Verify offline signature about wiring profits to a + * regular non-escrowed account of the exchange. + * + * @param wtid (random) wire transfer ID to be used + * @param date when was the profit drain approved (not exact time of execution) + * @param amount how much should be wired + * @param account_section configuration section of the + * exchange specifying the account to be debited + * @param payto_uri target account to be credited + * @param master_pub public key to verify signature against + * @param master_sig the signature + * @return #GNUNET_OK if the signature is valid + */ +enum GNUNET_GenericReturnValue +TALER_exchange_offline_profit_drain_verify ( + const struct TALER_WireTransferIdentifierRawP *wtid, + struct GNUNET_TIME_Timestamp date, + const struct TALER_Amount *amount, + const char *account_section, + const char *payto_uri, + const struct TALER_MasterPublicKeyP *master_pub, + const struct TALER_MasterSignatureP *master_sig); + + /** * Create security module EdDSA signature. * diff --git a/src/include/taler_exchangedb_lib.h b/src/include/taler_exchangedb_lib.h index 7f466728a..45889435a 100644 --- a/src/include/taler_exchangedb_lib.h +++ b/src/include/taler_exchangedb_lib.h @@ -95,7 +95,7 @@ struct TALER_EXCHANGEDB_AccountInfo * @param[out] ret where the resulting total is to be stored * @return #GNUNET_OK on success, #GNUNET_SYSERR on errors */ -int +enum GNUNET_GenericReturnValue TALER_EXCHANGEDB_calculate_transaction_list_totals ( struct TALER_EXCHANGEDB_TransactionList *tl, const struct TALER_Amount *off, diff --git a/src/util/offline_signatures.c b/src/util/offline_signatures.c index 54da2b114..108c665ef 100644 --- a/src/util/offline_signatures.c +++ b/src/util/offline_signatures.c @@ -1145,4 +1145,88 @@ TALER_exchange_offline_partner_details_verify ( } +GNUNET_NETWORK_STRUCT_BEGIN + +/** + * Message signed by account to drain profits + * from the escrow account of the exchange. + */ +struct TALER_DrainProfitPS +{ + + /** + * Purpose is #TALER_SIGNATURE_MASTER_DRAIN_PROFITS + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + struct TALER_WireTransferIdentifierRawP wtid; + struct GNUNET_TIME_TimestampNBO date; + struct TALER_AmountNBO amount; + struct GNUNET_HashCode h_section; + struct TALER_PaytoHashP h_payto; +}; + +GNUNET_NETWORK_STRUCT_END + + +void +TALER_exchange_offline_profit_drain_sign ( + const struct TALER_WireTransferIdentifierRawP *wtid, + struct GNUNET_TIME_Timestamp date, + const struct TALER_Amount *amount, + const char *account_section, + const char *payto_uri, + const struct TALER_MasterPrivateKeyP *master_priv, + struct TALER_MasterSignatureP *master_sig) +{ + struct TALER_DrainProfitPS wd = { + .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_DRAIN_PROFIT), + .purpose.size = htonl (sizeof (wd)), + .wtid = *wtid, + .date = GNUNET_TIME_timestamp_hton (date), + }; + + GNUNET_CRYPTO_hash (account_section, + strlen (account_section) + 1, + &wd.h_section); + TALER_payto_hash (payto_uri, + &wd.h_payto); + TALER_amount_hton (&wd.amount, + amount); + GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv, + &wd, + &master_sig->eddsa_signature); +} + + +enum GNUNET_GenericReturnValue +TALER_exchange_offline_profit_drain_verify ( + const struct TALER_WireTransferIdentifierRawP *wtid, + struct GNUNET_TIME_Timestamp date, + const struct TALER_Amount *amount, + const char *account_section, + const char *payto_uri, + const struct TALER_MasterPublicKeyP *master_pub, + const struct TALER_MasterSignatureP *master_sig) +{ + struct TALER_DrainProfitPS wd = { + .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_DRAIN_PROFIT), + .purpose.size = htonl (sizeof (wd)), + .wtid = *wtid, + .date = GNUNET_TIME_timestamp_hton (date), + }; + + GNUNET_CRYPTO_hash (account_section, + strlen (account_section) + 1, + &wd.h_section); + TALER_payto_hash (payto_uri, + &wd.h_payto); + TALER_amount_hton (&wd.amount, + amount); + return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_DRAIN_PROFIT, + &wd, + &master_sig->eddsa_signature, + &master_pub->eddsa_pub); +} + + /* end of offline_signatures.c */