From 41399bc2243d0bbe2918dba5b753111fb203cff7 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 23 Mar 2022 06:54:43 +0100 Subject: [PATCH] revise P2P signatures and signing schema to address recently discovered design concern resulting in the split of the purse key into purse-contract and purse-merge keys --- src/exchangedb/drop0001.sql | 5 ++ src/exchangedb/exchange-0001.sql | 120 ++++++++++++++------------ src/include/taler_crypto_lib.h | 104 +++++++++++++++------- src/include/taler_exchangedb_plugin.h | 116 +++++++++++++++++++++++++ src/util/wallet_signatures.c | 74 ++++++++-------- 5 files changed, 300 insertions(+), 119 deletions(-) diff --git a/src/exchangedb/drop0001.sql b/src/exchangedb/drop0001.sql index 49d9d3639..c969286a0 100644 --- a/src/exchangedb/drop0001.sql +++ b/src/exchangedb/drop0001.sql @@ -79,6 +79,11 @@ DROP TABLE IF EXISTS denominations CASCADE; DROP TABLE IF EXISTS cs_nonce_locks CASCADE; DROP FUNCTION IF EXISTS add_constraints_to_cs_nonce_locks_partition; +DROP TABLE IF EXISTS deposits_by_coin CASCADE; +DROP TABLE IF EXISTS global_fee CASCADE; +DROP TABLE IF EXISTS recoup_by_reserve CASCADE; + + DROP TABLE IF EXISTS partners CASCADE; DROP TABLE IF EXISTS mergers CASCADE; DROP TABLE IF EXISTS contracts CASCADE; diff --git a/src/exchangedb/exchange-0001.sql b/src/exchangedb/exchange-0001.sql index a12789c5e..5a4199040 100644 --- a/src/exchangedb/exchange-0001.sql +++ b/src/exchangedb/exchange-0001.sql @@ -1403,45 +1403,85 @@ COMMENT ON COLUMN partners.partner_base_url COMMENT ON COLUMN partners.master_sig IS 'signature of our master public key affirming the partnership, of purpose TALER_SIGNATURE_MASTER_PARTNER_DETAILS'; -CREATE TABLE IF NOT EXISTS mergers - (merge_request_serial_id BIGSERIAL UNIQUE - ,partner_serial_id INT8 REFERENCES partners(partner_serial_id) ON DELETE CASCADE - ,reserve_pub BYTEA NOT NULL REFERENCES reserves (reserve_pub) ON DELETE CASCADE - ,reserve_sig BYTEA NOT NULL CHECK (LENGTH(reserve_sig)=64) + +CREATE TABLE IF NOT EXISTS purse_requests + (purse_deposit_serial_id BIGSERIAL UNIQUE ,purse_pub BYTEA NOT NULL CHECK (LENGTH(purse_pub)=32) - ,purse_sig BYTEA NOT NULL CHECK (LENGTH(purse_sig)=64) - ,merge_timestamp INT8 NOT NULL + ,merge_pub BYTEA NOT NULL CHECK (LENGTH(merge_pub)=32) ,purse_expiration INT8 NOT NULL ,h_contract_terms BYTEA NOT NULL CHECK (LENGTH(h_contract_terms)=64) - ,purse_val INT8 NOT NULL - ,purse_frac INT4 NOT NULL + ,amount_with_fee_val INT8 NOT NULL + ,amount_with_fee_frac INT4 NOT NULL + ,balance_val INT8 NOT NULL + ,balance_frac INT4 NOT NULL + ,purse_sig BYTEA NOT NULL CHECK(LENGTH(purse_sig)=64) + ,PRIMARY KEY (purse_pub) + ); -- partition by purse_pub +COMMENT ON TABLE purse_requests + IS 'Requests establishing purses, associating them with a contract but without a target reserve'; +COMMENT ON COLUMN purse_requests.purse_pub + IS 'Public key of the purse'; +COMMENT ON COLUMN purse_requests.purse_expiration + IS 'When the purse is set to expire'; +COMMENT ON COLUMN purse_requests.h_contract_terms + IS 'Hash of the contract the parties are to agree to'; +COMMENT ON COLUMN purse_requests.amount_with_fee_val + IS 'Total amount expected to be in the purse'; +COMMENT ON COLUMN purse_requests.balance_val + IS 'Total amount actually in the purse'; +COMMENT ON COLUMN purse_requests.purse_sig + IS 'Signature of the purse affirming the purse parameters, of type TALER_SIGNATURE_PURSE_REQUEST'; + + +CREATE TABLE IF NOT EXISTS purse_merges + (purse_merge_request_serial_id BIGSERIAL -- UNIQUE + ,partner_serial_id INT8 REFERENCES partners(partner_serial_id) ON DELETE CASCADE + ,reserve_pub BYTEA NOT NULL CHECK(length(reserve_pub)=32)--REFERENCES reserves (reserve_pub) ON DELETE CASCADE + ,purse_pub BYTEA NOT NULL CHECK (LENGTH(purse_pub)=32) --REFERENCES purse_requests (purse_pub) ON DELETE CASCADE + ,merge_sig BYTEA NOT NULL CHECK (LENGTH(merge_sig)=64) + ,merge_timestamp INT8 NOT NULL ,PRIMARY KEY (purse_pub) ); -- partition by purse_pub; plus materialized index by reserve_pub! -COMMENT ON TABLE mergers - IS 'Merge requests where a purse- and account-owner requested merging the purse into the account'; -COMMENT ON COLUMN mergers.partner_serial_id +COMMENT ON TABLE purse_merges + IS 'Merge requests where a purse-owner requested merging the purse into the account'; +COMMENT ON COLUMN purse_merges.partner_serial_id IS 'identifies the partner exchange, NULL in case the target reserve lives at this exchange'; -COMMENT ON COLUMN mergers.reserve_pub +COMMENT ON COLUMN purse_merges.reserve_pub IS 'public key of the target reserve'; -COMMENT ON COLUMN mergers.purse_pub +COMMENT ON COLUMN purse_merges.purse_pub IS 'public key of the purse'; -COMMENT ON COLUMN mergers.reserve_sig - IS 'signature by the reserve private key affirming the merge, of type TALER_SIGNATURE_WALLET_ACCOUNT_MERGE'; -COMMENT ON COLUMN mergers.purse_sig +COMMENT ON COLUMN purse_merges.merge_sig IS 'signature by the purse private key affirming the merge, of type TALER_SIGNATURE_WALLET_PURSE_MERGE'; -COMMENT ON COLUMN mergers.merge_timestamp +COMMENT ON COLUMN purse_merges.merge_timestamp IS 'when was the merge message signed'; -COMMENT ON COLUMN mergers.purse_expiration - IS 'when is the purse set to expire'; -COMMENT ON COLUMN mergers.h_contract_terms - IS 'hash of the contract terms both sides are to agree upon'; -COMMENT ON COLUMN mergers.purse_val - IS 'amount to be transferred from the purse to the reserve (excludes deposit fees)'; -CREATE INDEX IF NOT EXISTS mergers_reserve_pub - ON mergers (reserve_pub); -COMMENT ON INDEX mergers_reserve_pub +CREATE INDEX IF NOT EXISTS purse_merges_reserve_pub + ON purse_merges (reserve_pub); +COMMENT ON INDEX purse_merges_reserve_pub IS 'needed in reserve history computation'; + +CREATE TABLE IF NOT EXISTS account_mergers + (account_merge_request_serial_id BIGSERIAL -- UNIQUE + ,reserve_pub BYTEA NOT NULL CHECK (LENGTH(reserve_pub)=32) -- REFERENCES reserves (reserve_pub) ON DELETE CASCADE + ,reserve_sig BYTEA NOT NULL CHECK (LENGTH(reserve_sig)=64) + ,purse_pub BYTEA NOT NULL CHECK (LENGTH(purse_pub)=32) -- REFERENCES purse_requests (purse_pub) + ,PRIMARY KEY (reserve_pub) + ); -- partition by purse_pub; plus materialized index by reserve_pub! +COMMENT ON TABLE account_mergers + IS 'Merge requests where a purse- and account-owner requested merging the purse into the account'; +COMMENT ON COLUMN account_mergers.reserve_pub + IS 'public key of the target reserve'; +COMMENT ON COLUMN account_mergers.purse_pub + IS 'public key of the purse'; +COMMENT ON COLUMN account_mergers.reserve_sig + IS 'signature by the reserve private key affirming the merge, of type TALER_SIGNATURE_WALLET_ACCOUNT_MERGE'; + +CREATE INDEX IF NOT EXISTS account_mergers_purse_pub + ON account_mergers (purse_pub); +COMMENT ON INDEX account_mergers_purse_pub + IS 'needed when checking for a purse merge status'; + + CREATE TABLE IF NOT EXISTS contracts (contract_serial_id BIGSERIAL UNIQUE ,purse_pub BYTEA NOT NULL CHECK (LENGTH(purse_pub)=32) @@ -1492,32 +1532,6 @@ COMMENT ON COLUMN close_requests.reserve_sig COMMENT ON COLUMN close_requests.close_val IS 'Balance of the reserve at the time of closing, to be wired to the associated bank account (minus the closing fee)'; -CREATE TABLE IF NOT EXISTS purse_requests - (purse_deposit_serial_id BIGSERIAL UNIQUE - ,purse_pub BYTEA NOT NULL CHECK (LENGTH(purse_pub)=32) - ,purse_expiration INT8 NOT NULL - ,h_contract_terms BYTEA NOT NULL CHECK (LENGTH(h_contract_terms)=64) - ,amount_with_fee_val INT8 NOT NULL - ,amount_with_fee_frac INT4 NOT NULL - ,balance_val INT8 NOT NULL - ,balance_frac INT4 NOT NULL - ,purse_sig BYTEA NOT NULL CHECK(LENGTH(purse_sig)=64) - ,PRIMARY KEY (purse_pub) - ); -- partition by purse_pub -COMMENT ON TABLE purse_requests - IS 'Requests establishing purses, associating them with a contract but without a target reserve'; -COMMENT ON COLUMN purse_requests.purse_pub - IS 'Public key of the purse'; -COMMENT ON COLUMN purse_requests.purse_expiration - IS 'When the purse is set to expire'; -COMMENT ON COLUMN purse_requests.h_contract_terms - IS 'Hash of the contract the parties are to agree to'; -COMMENT ON COLUMN purse_requests.amount_with_fee_val - IS 'Total amount expected to be in the purse'; -COMMENT ON COLUMN purse_requests.balance_val - IS 'Total amount actually in the purse'; -COMMENT ON COLUMN purse_requests.purse_sig - IS 'Signature of the purse affirming the purse parameters, of type TALER_SIGNATURE_PURSE_REQUEST'; CREATE TABLE IF NOT EXISTS purse_deposits (purse_deposit_serial_id BIGSERIAL UNIQUE diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h index 809c6a8fe..ba7f05bcf 100644 --- a/src/include/taler_crypto_lib.h +++ b/src/include/taler_crypto_lib.h @@ -406,9 +406,9 @@ struct TALER_AgeCommitmentPublicKeyP /** - * @brief Type of online public keys used by the wallet to establish a purse. + * @brief Type of online public keys used by the wallet to establish a purse and the associated contract meta data. */ -struct TALER_PursePublicKeyP +struct TALER_PurseContractPublicKeyP { /** * Taler uses EdDSA for purse message signing. @@ -418,10 +418,10 @@ struct TALER_PursePublicKeyP /** - * @brief Type of online private keys used by the wallet for - * a purse. + * @brief Type of online private keys used by the wallet to + * bind a purse to a particular contract (and other meta data). */ -struct TALER_PursePrivateKeyP +struct TALER_PurseContractPrivateKeyP { /** * Taler uses EdDSA for online signatures sessions. @@ -431,9 +431,47 @@ struct TALER_PursePrivateKeyP /** - * @brief Type of signatures used by the wallet to sign purse messages online. + * @brief Type of signatures used by the wallet to sign purse creation messages online. */ -struct TALER_PurseSignatureP +struct TALER_PurseContractSignatureP +{ + /** + * Taler uses EdDSA for online signatures sessions. + */ + struct GNUNET_CRYPTO_EddsaSignature eddsa_signature; +}; + + +/** + * @brief Type of online public keys used by the wallet to + * sign a merge of a purse into an account. + */ +struct TALER_PurseMergePublicKeyP +{ + /** + * Taler uses EdDSA for purse message signing. + */ + struct GNUNET_CRYPTO_EddsaPublicKey eddsa_pub; +}; + + +/** + * @brief Type of online private keys used by the wallet to + * sign a merge of a purse into an account. + */ +struct TALER_PurseMergePrivateKeyP +{ + /** + * Taler uses EdDSA for online signatures sessions. + */ + struct GNUNET_CRYPTO_EddsaPrivateKey eddsa_priv; +}; + + +/** + * @brief Type of signatures used by the wallet to sign purse merge requests online. + */ +struct TALER_PurseMergeSignatureP { /** * Taler uses EdDSA for online signatures sessions. @@ -2621,6 +2659,7 @@ TALER_exchange_deposit_confirm_verify ( * * @param purse_expiration when should the purse expire * @param h_contract_terms contract the two parties agree on + * @param merge_pub public key defining the merge capability * @param min_age age restriction to apply for deposits into the purse * @param amount total amount in the purse (including fees) * @param purse_priv key identifying the purse @@ -2630,10 +2669,11 @@ void TALER_wallet_purse_create_sign ( struct GNUNET_TIME_Timestamp purse_expiration, struct TALER_PrivateContractHashP *h_contract_terms, + const struct TALER_PurseMergePublicKeyP *merge_pub, uint32_t min_age, const struct TALER_Amount *amount, - const struct TALER_PursePrivateKeyP *purse_priv, - struct TALER_PurseSignatureP *purse_sig); + const struct TALER_PurseContractPrivateKeyP *purse_priv, + struct TALER_PurseContractSignatureP *purse_sig); /** @@ -2641,6 +2681,7 @@ TALER_wallet_purse_create_sign ( * * @param purse_expiration when should the purse expire * @param h_contract_terms contract the two parties agree on + * @param merge_pub public key defining the merge capability * @param min_age age restriction to apply for deposits into the purse * @param amount total amount in the purse (including fees) * @param purse_pub purse’s public key @@ -2651,10 +2692,11 @@ enum GNUNET_GenericReturnValue TALER_wallet_purse_create_verify ( struct GNUNET_TIME_Timestamp purse_expiration, struct TALER_PrivateContractHashP *h_contract_terms, + const struct TALER_PurseMergePublicKeyP *merge_pub, uint32_t min_age, const struct TALER_Amount *amount, - const struct TALER_PursePublicKeyP *purse_pub, - const struct TALER_PurseSignatureP *purse_sig); + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_PurseContractSignatureP *purse_sig); /** @@ -2665,8 +2707,8 @@ TALER_wallet_purse_create_verify ( */ void TALER_wallet_purse_status_sign ( - const struct TALER_PursePrivateKeyP *purse_priv, - struct TALER_PurseSignatureP *purse_sig); + const struct TALER_PurseContractPrivateKeyP *purse_priv, + struct TALER_PurseContractSignatureP *purse_sig); /** @@ -2678,8 +2720,8 @@ TALER_wallet_purse_status_sign ( */ enum GNUNET_GenericReturnValue TALER_wallet_purse_status_verify ( - const struct TALER_PursePublicKeyP *purse_pub, - const struct TALER_PurseSignatureP *purse_sig); + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_PurseContractSignatureP *purse_sig); /** @@ -2692,7 +2734,7 @@ TALER_wallet_purse_status_verify ( */ void TALER_wallet_purse_deposit_sign ( - const struct TALER_PursePublicKeyP *purse_pub, + const struct TALER_PurseContractPublicKeyP *purse_pub, const struct TALER_Amount *amount, const struct TALER_CoinSpendPrivateKeyP *coin_priv, struct TALER_CoinSpendSignatureP *coin_sig); @@ -2709,7 +2751,7 @@ TALER_wallet_purse_deposit_sign ( */ enum GNUNET_GenericReturnValue TALER_wallet_purse_deposit_verify ( - const struct TALER_PursePublicKeyP *purse_pub, + const struct TALER_PurseContractPublicKeyP *purse_pub, const struct TALER_Amount *amount, const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendSignatureP *coin_sig); @@ -2721,15 +2763,17 @@ TALER_wallet_purse_deposit_verify ( * @param reserve_url identifies the location of the reserve, * included public key must match @e reserve_priv * @param merge_timestamp time when the merge happened - * @param purse_priv key identifying the purse - * @param[out] purse_sig resulting signature + * @param purse_pub key identifying the purse + * @param merge_priv key identifying the merge capability + * @param[out] merge_sig resulting signature */ void TALER_wallet_purse_merge_sign ( const char *reserve_url, struct GNUNET_TIME_Timestamp merge_timestamp, - const struct TALER_PursePrivateKeyP *purse_priv, - struct TALER_PurseSignatureP *purse_sig); + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_PurseMergePrivateKeyP *merge_priv, + struct TALER_PurseMergeSignatureP *merge_sig); /** @@ -2739,22 +2783,22 @@ TALER_wallet_purse_merge_sign ( * included public key must match @e reserve_priv * @param merge_timestamp time when the merge happened * @param purse_pub public key of the purse to merge - * @param purse_sig the signature made with purpose #TALER_SIGNATURE_WALLET_PURSE_MERGE + * @param merge_pub public key of the merge capability + * @param merge_sig the signature made with purpose #TALER_SIGNATURE_WALLET_PURSE_MERGE * @return #GNUNET_OK if the signature is valid */ enum GNUNET_GenericReturnValue TALER_wallet_purse_merge_verify ( const char *reserve_url, struct GNUNET_TIME_Timestamp merge_timestamp, - const struct TALER_PursePublicKeyP *purse_pub, - const struct TALER_PurseSignatureP *purse_sig); + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_PurseMergePublicKeyP *merge_pub, + const struct TALER_PurseMergeSignatureP *merge_sig); /** * Sign a request by an account to merge a purse. * - * @param reserve_url identifies the location of the reserve, - * included public key must match @e reserve_priv * @param merge_timestamp time when the merge happened * @param purse_pub public key of the purse to merge * @param purse_expiration when should the purse expire @@ -2766,9 +2810,8 @@ TALER_wallet_purse_merge_verify ( */ void TALER_wallet_account_merge_sign ( - const char *reserve_url, struct GNUNET_TIME_Timestamp merge_timestamp, - const struct TALER_PursePublicKeyP *purse_pub, + const struct TALER_PurseContractPublicKeyP *purse_pub, struct GNUNET_TIME_Timestamp purse_expiration, struct TALER_PrivateContractHashP *h_contract_terms, const struct TALER_Amount *amount, @@ -2780,8 +2823,6 @@ TALER_wallet_account_merge_sign ( /** * Verify an account's request to merge a purse. * - * @param reserve_url identifies the location of the reserve, - * included public key must match @e reserve_priv * @param merge_timestamp time when the merge happened * @param purse_pub public key of the purse to merge * @param purse_expiration when should the purse expire @@ -2794,9 +2835,8 @@ TALER_wallet_account_merge_sign ( */ enum GNUNET_GenericReturnValue TALER_wallet_account_merge_verify ( - const char *reserve_url, struct GNUNET_TIME_Timestamp merge_timestamp, - const struct TALER_PursePublicKeyP *purse_pub, + const struct TALER_PurseContractPublicKeyP *purse_pub, struct GNUNET_TIME_Timestamp purse_expiration, struct TALER_PrivateContractHashP *h_contract_terms, const struct TALER_Amount *amount, diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h index 5b8aa53bd..074e952ea 100644 --- a/src/include/taler_exchangedb_plugin.h +++ b/src/include/taler_exchangedb_plugin.h @@ -4323,6 +4323,7 @@ struct TALER_EXCHANGEDB_Plugin enum GNUNET_DB_QueryStatus (*delete_shard_locks)(void *cls); + /** * Function called to save the configuration of an extension * (age-restriction, peer2peer, ...) @@ -4337,6 +4338,7 @@ struct TALER_EXCHANGEDB_Plugin const char *extension_name, const char *config); + /** * Function called to retrieve the configuration of an extension * (age-restriction, peer2peer, ...) @@ -4351,6 +4353,120 @@ struct TALER_EXCHANGEDB_Plugin const char *extension_name, char **config); + + enum GNUNET_DB_QueryStatus + (*insert_partner)(void *cls, + const struct TALER_MasterPublicKeyP *master_pub, + struct GNUNET_TIME_Timestamp start_date, + struct GNUNET_TIME_Timestamp end_date, + struct GNUNET_TIME_Relative wad_frequency, + const struct TALER_Amount *wad_fee, + const char *partner_base_url, + const struct TALER_MasterSignatureP *master_sig); + + + enum GNUNET_DB_QueryStatus + (*insert_contract)(void *cls, + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_ContractDiffiePublicP *pub_ckey, + size_t econtract_size, + const void *econtract); + + + enum GNUNET_DB_QueryStatus + (*select_contract)(void *cls, + const struct TALER_PurseContractPublicKeyP *purse_pub, + struct TALER_ContractDiffiePublicP *pub_ckey, + size_t *econtract_size, + void **econtract); + + + enum GNUNET_DB_QueryStatus + (*insert_purse_request)( + void *cls, + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_PurseMergePublicKeyP *merge_pub, + struct GNUNET_TIME_Timestamp purse_expiration, + const struct TALER_PrivateContractHashP *h_contract_terms, + const struct TALER_Amount *amount, + const struct TALER_PurseContractSignatureP *purse_sig); + + + enum GNUNET_DB_QueryStatus + (*select_purse_request)( + void *cls, + const struct TALER_PurseContractPublicKeyP *purse_pub, + struct TALER_PurseMergePublicKeyP *merge_pub, + struct GNUNET_TIME_Timestamp *purse_expiration, + struct TALER_PrivateContractHashP *h_contract_terms, + struct TALER_Amount *target_amount, + struct TALER_Amount *balance, + struct TALER_PurseContractSignatureP *purse_sig); + + + enum GNUNET_DB_QueryStatus + (*insert_purse_deposit)( + void *cls, + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_Amount *amount, + const struct TALER_CoinSpendSignatureP *coin_sig); + + + enum GNUNET_DB_QueryStatus + (*insert_purse_merge)( + void *cls, + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_PurseMergePublicKeyP *merge_pub, + const struct TALER_PurseMergeSignatureP *merge_sig, + const struct GNUNET_TIME_Timestamp merge_timestamp, + uint64_t partner_serial_id, + const struct TALER_ReservePublicKeyP *reserve_pub); + + + enum GNUNET_DB_QueryStatus + (*select_purse_merge)( + void *cls, + const struct TALER_PurseContractPublicKeyP *purse_pub, + struct TALER_PurseMergePublicKeyP *merge_pub, + struct TALER_PurseMergeSignatureP *merge_sig, + struct GNUNET_TIME_Timestamp *merge_timestamp, + uint64_t *partner_serial_id, + struct TALER_ReservePublicKeyP *reserve_pub); + + + enum GNUNET_DB_QueryStatus + (*insert_account_merge)( + void *cls, + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_ReserveSignatureP *reserve_sig); + + + enum GNUNET_DB_QueryStatus + (*select_account_merge)( + void *cls, + const struct TALER_PurseContractPublicKeyP *purse_pub, + struct TALER_ReservePublicKeyP *reserve_pub, + struct TALER_ReserveSignatureP *reserve_sig); + + + enum GNUNET_DB_QueryStatus + (*insert_history_request)( + void *cls, + const struct TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_ReserveSignatureP *reserve_sig, + struct GNUNET_TIME_Absolute request_timestamp, + const struct TALER_Amount *history); + + + enum GNUNET_DB_QueryStatus + (*insert_close_request)(void *cls, + const struct TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_ReserveSignatureP *reserve_sig, + struct TALER_Amount *final_balance); + + }; #endif /* _TALER_EXCHANGE_DB_H */ diff --git a/src/util/wallet_signatures.c b/src/util/wallet_signatures.c index c2303e064..097b8ed8a 100644 --- a/src/util/wallet_signatures.c +++ b/src/util/wallet_signatures.c @@ -778,6 +778,11 @@ struct TALER_PurseCreatePS */ struct TALER_PrivateContractHashP h_contract_terms; + /** + * Public key identifying the merge capability. + */ + struct TALER_PurseMergePublicKeyP merge_pub; + /** * Minimum age required for payments into this purse. */ @@ -790,16 +795,18 @@ void TALER_wallet_purse_create_sign ( struct GNUNET_TIME_Timestamp purse_expiration, struct TALER_PrivateContractHashP *h_contract_terms, + const struct TALER_PurseMergePublicKeyP *merge_pub, uint32_t min_age, const struct TALER_Amount *amount, - const struct TALER_PursePrivateKeyP *purse_priv, - struct TALER_PurseSignatureP *purse_sig) + const struct TALER_PurseContractPrivateKeyP *purse_priv, + struct TALER_PurseContractSignatureP *purse_sig) { struct TALER_PurseCreatePS pm = { .purpose.size = htonl (sizeof (pm)), .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_CREATE), .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration), .h_contract_terms = *h_contract_terms, + .merge_pub = *merge_pub, .min_age = htonl (min_age) }; @@ -815,16 +822,18 @@ enum GNUNET_GenericReturnValue TALER_wallet_purse_create_verify ( struct GNUNET_TIME_Timestamp purse_expiration, struct TALER_PrivateContractHashP *h_contract_terms, + const struct TALER_PurseMergePublicKeyP *merge_pub, uint32_t min_age, const struct TALER_Amount *amount, - const struct TALER_PursePublicKeyP *purse_pub, - const struct TALER_PurseSignatureP *purse_sig) + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_PurseContractSignatureP *purse_sig) { struct TALER_PurseCreatePS pm = { .purpose.size = htonl (sizeof (pm)), .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_CREATE), .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration), .h_contract_terms = *h_contract_terms, + .merge_pub = *merge_pub, .min_age = htonl (min_age) }; @@ -840,8 +849,8 @@ TALER_wallet_purse_create_verify ( void TALER_wallet_purse_status_sign ( - const struct TALER_PursePrivateKeyP *purse_priv, - struct TALER_PurseSignatureP *purse_sig) + const struct TALER_PurseContractPrivateKeyP *purse_priv, + struct TALER_PurseContractSignatureP *purse_sig) { struct GNUNET_CRYPTO_EccSignaturePurpose purpose = { .size = htonl (sizeof (purpose)), @@ -857,8 +866,8 @@ TALER_wallet_purse_status_sign ( enum GNUNET_GenericReturnValue TALER_wallet_purse_status_verify ( - const struct TALER_PursePublicKeyP *purse_pub, - const struct TALER_PurseSignatureP *purse_sig) + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_PurseContractSignatureP *purse_sig) { struct GNUNET_CRYPTO_EccSignaturePurpose purpose = { .size = htonl (sizeof (purpose)), @@ -891,14 +900,14 @@ struct TALER_PurseDepositPS /** * Purse to deposit funds into. */ - struct TALER_PursePublicKeyP purse_pub; + struct TALER_PurseContractPublicKeyP purse_pub; }; void TALER_wallet_purse_deposit_sign ( - const struct TALER_PursePublicKeyP *purse_pub, + const struct TALER_PurseContractPublicKeyP *purse_pub, const struct TALER_Amount *amount, const struct TALER_CoinSpendPrivateKeyP *coin_priv, struct TALER_CoinSpendSignatureP *coin_sig) @@ -919,7 +928,7 @@ TALER_wallet_purse_deposit_sign ( enum GNUNET_GenericReturnValue TALER_wallet_purse_deposit_verify ( - const struct TALER_PursePublicKeyP *purse_pub, + const struct TALER_PurseContractPublicKeyP *purse_pub, const struct TALER_Amount *amount, const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendSignatureP *coin_sig) @@ -956,6 +965,11 @@ struct TALER_PurseMergePS */ struct GNUNET_TIME_TimestampNBO merge_timestamp; + /** + * Which purse is being merged? + */ + struct TALER_PurseContractPublicKeyP purse_pub; + /** * Which reserve should the purse be merged with. * Hash of the reserve's payto:// URI. @@ -969,20 +983,22 @@ void TALER_wallet_purse_merge_sign ( const char *reserve_url, struct GNUNET_TIME_Timestamp merge_timestamp, - const struct TALER_PursePrivateKeyP *purse_priv, - struct TALER_PurseSignatureP *purse_sig) + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_PurseMergePrivateKeyP *merge_priv, + struct TALER_PurseMergeSignatureP *merge_sig) { struct TALER_PurseMergePS pm = { .purpose.size = htonl (sizeof (pm)), .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_MERGE), .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp), + .purse_pub = *purse_pub }; TALER_payto_hash (reserve_url, &pm.h_payto); - GNUNET_CRYPTO_eddsa_sign (&purse_priv->eddsa_priv, + GNUNET_CRYPTO_eddsa_sign (&merge_priv->eddsa_priv, &pm, - &purse_sig->eddsa_signature); + &merge_sig->eddsa_signature); } @@ -990,13 +1006,15 @@ enum GNUNET_GenericReturnValue TALER_wallet_purse_merge_verify ( const char *reserve_url, struct GNUNET_TIME_Timestamp merge_timestamp, - const struct TALER_PursePublicKeyP *purse_pub, - const struct TALER_PurseSignatureP *purse_sig) + const struct TALER_PurseContractPublicKeyP *purse_pub, + const struct TALER_PurseMergePublicKeyP *merge_pub, + const struct TALER_PurseMergeSignatureP *merge_sig) { struct TALER_PurseMergePS pm = { .purpose.size = htonl (sizeof (pm)), .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_MERGE), .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp), + .purse_pub = *purse_pub }; TALER_payto_hash (reserve_url, @@ -1004,8 +1022,8 @@ TALER_wallet_purse_merge_verify ( return GNUNET_CRYPTO_eddsa_verify ( TALER_SIGNATURE_WALLET_ACCOUNT_MERGE, &pm, - &purse_sig->eddsa_signature, - &purse_pub->eddsa_pub); + &merge_sig->eddsa_signature, + &merge_pub->eddsa_pub); } @@ -1030,12 +1048,6 @@ struct TALER_AccountMergePS */ struct TALER_AmountNBO purse_amount; - /** - * Which reserve should the purse be merged with. - * Hash of the reserve's payto:// URI. - */ - struct TALER_PaytoHashP h_payto; - /** * Contract this purse pays for. */ @@ -1044,7 +1056,7 @@ struct TALER_AccountMergePS /** * Purse to merge. */ - struct TALER_PursePublicKeyP purse_pub; + struct TALER_PurseContractPublicKeyP purse_pub; /** * Time when the purse is merged into the reserve. @@ -1060,9 +1072,8 @@ struct TALER_AccountMergePS void TALER_wallet_account_merge_sign ( - const char *reserve_url, struct GNUNET_TIME_Timestamp merge_timestamp, - const struct TALER_PursePublicKeyP *purse_pub, + const struct TALER_PurseContractPublicKeyP *purse_pub, struct GNUNET_TIME_Timestamp purse_expiration, struct TALER_PrivateContractHashP *h_contract_terms, const struct TALER_Amount *amount, @@ -1082,8 +1093,6 @@ TALER_wallet_account_merge_sign ( TALER_amount_hton (&pm.purse_amount, amount); - TALER_payto_hash (reserve_url, - &pm.h_payto); GNUNET_CRYPTO_eddsa_sign (&reserve_priv->eddsa_priv, &pm, &reserve_sig->eddsa_signature); @@ -1092,9 +1101,8 @@ TALER_wallet_account_merge_sign ( enum GNUNET_GenericReturnValue TALER_wallet_account_merge_verify ( - const char *reserve_url, struct GNUNET_TIME_Timestamp merge_timestamp, - const struct TALER_PursePublicKeyP *purse_pub, + const struct TALER_PurseContractPublicKeyP *purse_pub, struct GNUNET_TIME_Timestamp purse_expiration, struct TALER_PrivateContractHashP *h_contract_terms, const struct TALER_Amount *amount, @@ -1114,8 +1122,6 @@ TALER_wallet_account_merge_verify ( TALER_amount_hton (&pm.purse_amount, amount); - TALER_payto_hash (reserve_url, - &pm.h_payto); return GNUNET_CRYPTO_eddsa_verify ( TALER_SIGNATURE_WALLET_ACCOUNT_MERGE, &pm,