diff --git a/src/exchange/taler-exchange-httpd_kyc-wallet.c b/src/exchange/taler-exchange-httpd_kyc-wallet.c index 2f94d1a54..0d92efd3a 100644 --- a/src/exchange/taler-exchange-httpd_kyc-wallet.c +++ b/src/exchange/taler-exchange-httpd_kyc-wallet.c @@ -104,10 +104,6 @@ TEH_handler_kyc_wallet ( }; MHD_RESULT res; enum GNUNET_GenericReturnValue ret; - struct GNUNET_CRYPTO_EccSignaturePurpose purpose = { - .size = htonl (sizeof (purpose)), - .purpose = htonl (TALER_SIGNATURE_WALLET_ACCOUNT_SETUP) - }; (void) args; ret = TALER_MHD_parse_json_data (rc->connection, @@ -120,10 +116,8 @@ TEH_handler_kyc_wallet ( TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_EDDSA]++; if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify_ (TALER_SIGNATURE_WALLET_ACCOUNT_SETUP, - &purpose, - &reserve_sig.eddsa_signature, - &krc.reserve_pub.eddsa_pub)) + TALER_wallet_account_setup_verify (&krc.reserve_pub, + &reserve_sig)) { GNUNET_break_op (0); return TALER_MHD_reply_with_error ( diff --git a/src/exchangedb/exchange-0001.sql b/src/exchangedb/exchange-0001.sql index 80ade238c..0e49a9fc4 100644 --- a/src/exchangedb/exchange-0001.sql +++ b/src/exchangedb/exchange-0001.sql @@ -1407,7 +1407,6 @@ CREATE TABLE IF NOT EXISTS mergers (merge_request_serial_id BIGSERIAL UNIQUE ,reserve_pub BYTEA NOT NULL REFERENCES reserves (reserve_pub) ON DELETE CASCADE ,partner_serial_id INT8 REFERENCES partners(partner_serial_id) ON DELETE CASCADE - ,reserve_url TEXT NOT NULL ,purse_pub BYTEA NOT NULL CHECK (LENGTH(purse_pub)=32) ,reserve_sig BYTEA NOT NULL CHECK (LENGTH(reserve_sig)=64) ,purse_sig BYTEA NOT NULL CHECK (LENGTH(purse_sig)=64) @@ -1422,16 +1421,14 @@ 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 IS 'identifies the partner exchange, NULL in case the target reserve lives at this exchange'; -COMMENT ON COLUMN mergers.reserve_url - IS 'payto://-URL of the reserve, identifies the exchange and the reserve'; COMMENT ON COLUMN mergers.reserve_pub IS 'public key of the target reserve'; COMMENT ON COLUMN mergers.purse_pub IS 'public key of the purse'; COMMENT ON COLUMN mergers.reserve_sig - IS 'signature by the reserve private key affirming the merge'; + IS 'signature by the reserve private key affirming the merge, of type TALER_SIGNATURE_WALLET_ACCOUNT_MERGE'; COMMENT ON COLUMN mergers.purse_sig - IS 'signature by the purse private key affirming the merge'; + IS 'signature by the purse private key affirming the merge, of type TALER_SIGNATURE_WALLET_PURSE_MERGE'; COMMENT ON COLUMN mergers.merge_timestamp IS 'when was the merge message signed'; COMMENT ON COLUMN mergers.purse_expiration @@ -1502,6 +1499,8 @@ CREATE TABLE IF NOT EXISTS purse_requests ,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 @@ -1515,13 +1514,14 @@ 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 ,purse_pub BYTEA NOT NULL CHECK (LENGTH(purse_pub)=32) - ,purse_expiration INT8 NOT NULL ,coin_pub BYTEA NOT NULL REFERENCES known_coins (coin_pub) ON DELETE CASCADE ,amount_with_fee_val INT8 NOT NULL ,amount_with_fee_frac INT4 NOT NULL @@ -1532,8 +1532,6 @@ COMMENT ON TABLE purse_deposits IS 'Requests depositing coins into a purse'; COMMENT ON COLUMN purse_deposits.purse_pub IS 'Public key of the purse'; -COMMENT ON COLUMN purse_deposits.purse_expiration - IS 'When the purse is set to expire'; COMMENT ON COLUMN purse_deposits.coin_pub IS 'Public key of the coin being deposited'; COMMENT ON COLUMN purse_deposits.amount_with_fee_val diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h index 8786a3783..521a24aee 100644 --- a/src/include/taler_crypto_lib.h +++ b/src/include/taler_crypto_lib.h @@ -32,6 +32,16 @@ */ #define TALER_MAX_FRESH_COINS 256 +/** + * Cut-and-choose size for refreshing. Client looses the gamble (of + * unaccountable transfers) with probability 1/TALER_CNC_KAPPA. Refresh cost + * increases linearly with TALER_CNC_KAPPA, and 3 is sufficient up to a + * income/sales tax of 66% of total transaction value. As there is + * no good reason to change this security parameter, we declare it + * fixed and part of the protocol. + */ +#define TALER_CNC_KAPPA 3 + /* ****************** Coin crypto primitives ************* */ @@ -247,6 +257,30 @@ struct TALER_MasterPublicKeyP }; +/** + * @brief Type of the offline master public keys used by the exchange. + */ +struct TALER_MasterPrivateKeyP +{ + /** + * Taler uses EdDSA for the long-term offline master key. + */ + struct GNUNET_CRYPTO_EddsaPrivateKey eddsa_priv; +}; + + +/** + * @brief Type of signatures by the offline master public key used by the exchange. + */ +struct TALER_MasterSignatureP +{ + /** + * Taler uses EdDSA for the long-term offline master key. + */ + struct GNUNET_CRYPTO_EddsaSignature eddsa_signature; +}; + + /** * @brief Type of the private key used by the auditor. */ @@ -283,30 +317,6 @@ struct TALER_AuditorSignatureP }; -/** - * @brief Type of the offline master public keys used by the exchange. - */ -struct TALER_MasterPrivateKeyP -{ - /** - * Taler uses EdDSA for the long-term offline master key. - */ - struct GNUNET_CRYPTO_EddsaPrivateKey eddsa_priv; -}; - - -/** - * @brief Type of signatures by the offline master public key used by the exchange. - */ -struct TALER_MasterSignatureP -{ - /** - * Taler uses EdDSA for the long-term offline master key. - */ - struct GNUNET_CRYPTO_EddsaSignature eddsa_signature; -}; - - /** * @brief Type of public keys for Taler coins. The same key material is used * for EdDSA and ECDHE operations. @@ -333,6 +343,18 @@ struct TALER_CoinSpendPrivateKeyP struct GNUNET_CRYPTO_EddsaPrivateKey eddsa_priv; }; +/** + * @brief Type of signatures made with Taler coins. + */ +struct TALER_CoinSpendSignatureP +{ + /** + * Taler uses EdDSA for coins. + */ + struct GNUNET_CRYPTO_EddsaSignature eddsa_signature; +}; + + /** * @brief Type of private keys for age commitment in coins. */ @@ -358,12 +380,37 @@ struct TALER_AgeCommitmentPublicKeyP /** - * @brief Type of signatures made with Taler coins. + * @brief Type of online public keys used by the wallet to establish a purse. */ -struct TALER_CoinSpendSignatureP +struct TALER_PursePublicKeyP { /** - * Taler uses EdDSA for coins. + * Taler uses EdDSA for purse message signing. + */ + struct GNUNET_CRYPTO_EddsaPublicKey eddsa_pub; +}; + + +/** + * @brief Type of online private keys used by the wallet for + * a purse. + */ +struct TALER_PursePrivateKeyP +{ + /** + * Taler uses EdDSA for online signatures sessions. + */ + struct GNUNET_CRYPTO_EddsaPrivateKey eddsa_priv; +}; + + +/** + * @brief Type of signatures used by the wallet to sign purse messages online. + */ +struct TALER_PurseSignatureP +{ + /** + * Taler uses EdDSA for online signatures sessions. */ struct GNUNET_CRYPTO_EddsaSignature eddsa_signature; }; @@ -2542,11 +2589,226 @@ TALER_exchange_deposit_confirm_verify ( /* ********************* wallet signing ************************** */ + +/** + * Sign a request to create a purse. + * + * @param purse_expiration when should the purse expire + * @param h_contract_terms contract the two parties agree on + * @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 + * @param[out] purse_sig resulting signature + */ +void +TALER_wallet_purse_create_sign ( + struct GNUNET_TIME_Timestamp purse_expiration, + struct TALER_PrivateContractHashP *h_contract_terms, + uint32_t min_age, + const struct TALER_Amount *amount, + const struct TALER_PursePrivateKeyP *purse_priv, + struct TALER_PurseSignatureP *purse_sig); + + +/** + * Verify a purse creation request. + * + * @param purse_expiration when should the purse expire + * @param h_contract_terms contract the two parties agree on + * @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 + * @param purse_sig the signature made with purpose #TALER_SIGNATURE_WALLET_PURSE_CREATE + * @return #GNUNET_OK if the signature is valid + */ +enum GNUNET_GenericReturnValue +TALER_wallet_purse_create_verify ( + struct GNUNET_TIME_Timestamp purse_expiration, + struct TALER_PrivateContractHashP *h_contract_terms, + uint32_t min_age, + const struct TALER_Amount *amount, + const struct TALER_PursePublicKeyP *purse_pub, + const struct TALER_PurseSignatureP *purse_sig); + + +/** + * Sign a request to inquire about a purse's status. + * + * @param purse_priv key identifying the purse + * @param[out] purse_sig resulting signature + */ +void +TALER_wallet_purse_status_sign ( + const struct TALER_PursePrivateKeyP *purse_priv, + struct TALER_PurseSignatureP *purse_sig); + + +/** + * Verify a purse status request signature. + * + * @param purse_pub purse’s public key + * @param purse_sig the signature made with purpose #TALER_SIGNATURE_WALLET_PURSE_STATUS_REQUEST + * @return #GNUNET_OK if the signature is valid + */ +enum GNUNET_GenericReturnValue +TALER_wallet_purse_status_verify ( + const struct TALER_PursePublicKeyP *purse_pub, + const struct TALER_PurseSignatureP *purse_sig); + + +/** + * Sign a request to deposit a coin into a purse. + * + * @param purse_pub purse’s public key + * @param amount amount of the coin's value to transfer to the purse + * @param coin_priv key identifying the coin to be deposited + * @param[out] coin_sig resulting signature + */ +void +TALER_wallet_purse_deposit_sign ( + const struct TALER_PursePublicKeyP *purse_pub, + const struct TALER_Amount *amount, + const struct TALER_CoinSpendPrivateKeyP *coin_priv, + struct TALER_CoinSpendSignatureP *coin_sig); + + +/** + * Verify a purse deposit request. + * + * @param purse_pub purse’s public key + * @param amount amount of the coin's value to transfer to the purse + * @param coin_pub key identifying the coin that is being deposited + * @param[out] coin_sig resulting signature + * @return #GNUNET_OK if the signature is valid + */ +enum GNUNET_GenericReturnValue +TALER_wallet_purse_deposit_verify ( + const struct TALER_PursePublicKeyP *purse_pub, + const struct TALER_Amount *amount, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_CoinSpendSignatureP *coin_sig); + + +/** + * Sign a request by a purse to merge it into an account. + * + * @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 + */ +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); + + +/** + * Verify a purse merge request. + * + * @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_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); + + +/** + * 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 + * @param h_contract_terms contract the two parties agree on + * @param amount total amount in the purse (including fees) + * @param min_age age restriction to apply for deposits into the purse + * @param reserve_priv key identifying the reserve + * @param[out] reserve_sig resulting signature + */ +void +TALER_wallet_account_merge_sign ( + const char *reserve_url, + struct GNUNET_TIME_Timestamp merge_timestamp, + const struct TALER_PursePublicKeyP *purse_pub, + struct GNUNET_TIME_Timestamp purse_expiration, + struct TALER_PrivateContractHashP *h_contract_terms, + const struct TALER_Amount *amount, + uint32_t min_age, + const struct TALER_ReservePrivateKeyP *reserve_priv, + struct TALER_ReserveSignatureP *reserve_sig); + + +/** + * 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 + * @param h_contract_terms contract the two parties agree on + * @param amount total amount in the purse (including fees) + * @param min_age age restriction to apply for deposits into the purse + * @param reserve_pub account’s public key + * @param reserve_sig the signature made with purpose #TALER_SIGNATURE_WALLET_ACCOUNT_MERGE + * @return #GNUNET_OK if the signature is valid + */ +enum GNUNET_GenericReturnValue +TALER_wallet_account_merge_verify ( + const char *reserve_url, + struct GNUNET_TIME_Timestamp merge_timestamp, + const struct TALER_PursePublicKeyP *purse_pub, + struct GNUNET_TIME_Timestamp purse_expiration, + struct TALER_PrivateContractHashP *h_contract_terms, + const struct TALER_Amount *amount, + uint32_t min_age, + const struct TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_ReserveSignatureP *reserve_sig); + + +/** + * Sign a request to delete/close an account. + * + * @param reserve_priv key identifying the reserve + * @param[out] reserve_sig resulting signature + */ +void +TALER_wallet_account_close_sign ( + const struct TALER_ReservePrivateKeyP *reserve_priv, + struct TALER_ReserveSignatureP *reserve_sig); + + +/** + * Verify wallet request to close an account. + * + * @param reserve_pub account’s public key + * @param reserve_sig the signature made with purpose #TALER_SIGNATURE_WALLET_RESERVE_CLOSE + * @return #GNUNET_OK if the signature is valid + */ +enum GNUNET_GenericReturnValue +TALER_wallet_account_close_verify ( + const struct TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_ReserveSignatureP *reserve_sig); + + /** * Sign a request by a wallet to perform a KYC check. * * @param reserve_priv key identifying the wallet/account - * @param reserve_sig resulting signature + * @param[out] reserve_sig resulting signature */ void TALER_wallet_account_setup_sign ( @@ -2554,6 +2816,19 @@ TALER_wallet_account_setup_sign ( struct TALER_ReserveSignatureP *reserve_sig); +/** + * Verify account setup request. + * + * @param reserve_pub reserve the setup request was for + * @param reserve_sig resulting signature + * @return #GNUNET_OK if the signature is valid + */ +enum GNUNET_GenericReturnValue +TALER_wallet_account_setup_verify ( + const struct TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_ReserveSignatureP *reserve_sig); + + /** * Sign a deposit permission. Function for wallets. * diff --git a/src/include/taler_signatures.h b/src/include/taler_signatures.h index 2aa826200..c730d2412 100644 --- a/src/include/taler_signatures.h +++ b/src/include/taler_signatures.h @@ -31,17 +31,6 @@ #include "taler_amount_lib.h" #include "taler_crypto_lib.h" -/** - * Cut-and-choose size for refreshing. Client looses the gamble (of - * unaccountable transfers) with probability 1/TALER_CNC_KAPPA. Refresh cost - * increases linearly with TALER_CNC_KAPPA, and 3 is sufficient up to a - * income/sales tax of 66% of total transaction value. As there is - * no good reason to change this security parameter, we declare it - * fixed and part of the protocol. - */ -#define TALER_CNC_KAPPA 3 - - /*********************************************/ /* Exchange offline signatures (with master key) */ /*********************************************/ @@ -220,12 +209,6 @@ */ #define TALER_SIGNATURE_MERCHANT_PAYMENT_OK 1104 -/** - * Signature where the merchant confirms that the user replayed - * a payment for a browser session. - */ -#define TALER_SIGNATURE_MERCHANT_PAY_SESSION 1106 - /** * Signature where the merchant confirms its own (salted) * wire details (not yet really used). @@ -293,6 +276,36 @@ */ #define TALER_SIGNATURE_WALLET_RESERVE_STATUS 1209 +/** + * Request purse creation (without reserve). + */ +#define TALER_SIGNATURE_WALLET_PURSE_CREATE 1210 + +/** + * Request coin to be deposited into a purse. + */ +#define TALER_SIGNATURE_WALLET_PURSE_DEPOSIT 1211 + +/** + * Request purse status. + */ +#define TALER_SIGNATURE_WALLET_PURSE_STATUS 1212 + +/** + * Request purse to be merged with a reserve (by purse). + */ +#define TALER_SIGNATURE_WALLET_PURSE_MERGE 1213 + +/** + * Request purse to be merged with a reserve (by account). + */ +#define TALER_SIGNATURE_WALLET_ACCOUNT_MERGE 1214 + +/** + * Request account to be closed. + */ +#define TALER_SIGNATURE_WALLET_RESERVE_CLOSE 1215 + /******************************/ /* Security module signatures */ @@ -418,207 +431,6 @@ struct TALER_SigningKeyAnnouncementPS }; -/** - * @brief Format used for to allow the wallet to authenticate - * link data provided by the exchange. - */ -struct TALER_LinkDataPS -{ - - /** - * Purpose must be #TALER_SIGNATURE_WALLET_COIN_LINK. - * Used with an EdDSA signature of a `struct TALER_CoinPublicKeyP`. - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * Hash of the denomination public key of the new coin. - */ - struct TALER_DenominationHashP h_denom_pub; - - /** - * Transfer public key (for which the private key was not revealed) - */ - struct TALER_TransferPublicKeyP transfer_pub; - - /** - * Hash of the age commitment, if applicable. Can be all zero - */ - struct TALER_AgeCommitmentHash h_age_commitment; - - /** - * Hash of the blinded new coin. - */ - struct TALER_BlindedCoinHashP coin_envelope_hash; -}; - - -/** - * Response by which a wallet requests an account status. - */ -struct TALER_ReserveStatusRequestPS -{ - - /** - * Purpose is #TALER_SIGNATURE_WALLET_RESERVE_STATUS - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * When did the wallet make the requst. - */ - struct GNUNET_TIME_TimestampNBO request_timestamp; - -}; - - -/** - * Response by which a wallet requests a full - * reserve history and indicates it is willing - * to pay for it. - */ -struct TALER_ReserveHistoryRequestPS -{ - - /** - * Purpose is #TALER_SIGNATURE_WALLET_RESERVE_HISTORY - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * When did the wallet make the requst. - */ - struct GNUNET_TIME_TimestampNBO request_timestamp; - - /** - * How much does the exchange charge for the history? - */ - struct TALER_AmountNBO history_fee; - -}; - - -/** - * @brief Format used for to generate the signature on a request to withdraw - * coins from a reserve. - */ -struct TALER_WithdrawRequestPS -{ - - /** - * Purpose must be #TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW. - * Used with an EdDSA signature of a `struct TALER_ReservePublicKeyP`. - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * Value of the coin being exchanged (matching the denomination key) - * plus the transaction fee. We include this in what is being - * signed so that we can verify a reserve's remaining total balance - * without needing to access the respective denomination key - * information each time. - */ - struct TALER_AmountNBO amount_with_fee; - - /** - * Hash of the denomination public key for the coin that is withdrawn. - */ - struct TALER_DenominationHashP h_denomination_pub GNUNET_PACKED; - - /** - * Hash of the (blinded) message to be signed by the Exchange. - */ - struct TALER_BlindedCoinHashP h_coin_envelope GNUNET_PACKED; -}; - - -/** - * @brief Format used to generate the signature on a request to deposit - * a coin into the account of a merchant. - */ -struct TALER_DepositRequestPS -{ - /** - * Purpose must be #TALER_SIGNATURE_WALLET_COIN_DEPOSIT. - * Used for an EdDSA signature with the `struct TALER_CoinSpendPublicKeyP`. - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * Hash over the contract for which this deposit is made. - */ - struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED; - - /** - * Hash over the age commitment that went into the coin. Maybe all zero, if - * age commitment isn't applicable to the denomination. - */ - struct TALER_AgeCommitmentHash h_age_commitment GNUNET_PACKED; - - /** - * Hash over extension attributes shared with the exchange. - */ - struct TALER_ExtensionContractHashP h_extensions GNUNET_PACKED; - - /** - * Hash over the wiring information of the merchant. - */ - struct TALER_MerchantWireHashP h_wire GNUNET_PACKED; - - /** - * Hash over the denomination public key used to sign the coin. - */ - struct TALER_DenominationHashP h_denom_pub GNUNET_PACKED; - - /** - * Time when this request was generated. Used, for example, to - * assess when (roughly) the income was achieved for tax purposes. - * Note that the Exchange will only check that the timestamp is not "too - * far" into the future (i.e. several days). The fact that the - * timestamp falls within the validity period of the coin's - * denomination key is irrelevant for the validity of the deposit - * request, as obviously the customer and merchant could conspire to - * set any timestamp. Also, the Exchange must accept very old deposit - * requests, as the merchant might have been unable to transmit the - * deposit request in a timely fashion (so back-dating is not - * prevented). - */ - struct GNUNET_TIME_TimestampNBO wallet_timestamp; - - /** - * How much time does the merchant have to issue a refund request? - * Zero if refunds are not allowed. After this time, the coin - * cannot be refunded. - */ - struct GNUNET_TIME_TimestampNBO refund_deadline; - - /** - * Amount to be deposited, including deposit fee charged by the - * exchange. This is the total amount that the coin's value at the exchange - * will be reduced by. - */ - struct TALER_AmountNBO amount_with_fee; - - /** - * Depositing fee charged by the exchange. This must match the Exchange's - * denomination key's depositing fee. If the client puts in an - * invalid deposit fee (too high or too low) that does not match the - * Exchange's denomination key, the deposit operation is invalid and - * will be rejected by the exchange. The @e amount_with_fee minus the - * @e deposit_fee is the amount that will be transferred to the - * account identified by @e h_wire. - */ - struct TALER_AmountNBO deposit_fee; - - /** - * The Merchant's public key. Allows the merchant to later refund - * the transaction or to inquire about the wire transfer identifier. - */ - struct TALER_MerchantPublicKeyP merchant; - -}; - - /** * @brief Format used to generate the signature on a confirmation * from the exchange that a deposit request succeeded. @@ -688,42 +500,6 @@ struct TALER_DepositConfirmationPS }; -/** - * @brief Format used to generate the signature on a request to refund - * a coin into the account of the customer. - */ -struct TALER_RefundRequestPS -{ - /** - * Purpose must be #TALER_SIGNATURE_MERCHANT_REFUND. - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * Hash over the proposal data to identify the contract - * which is being refunded. - */ - struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED; - - /** - * The coin's public key. This is the value that must have been - * signed (blindly) by the Exchange. - */ - struct TALER_CoinSpendPublicKeyP coin_pub; - - /** - * Merchant-generated transaction ID for the refund. - */ - uint64_t rtransaction_id GNUNET_PACKED; - - /** - * Amount to be refunded, including refund fee charged by the - * exchange to the customer. - */ - struct TALER_AmountNBO refund_amount; -}; - - /** * @brief Format used to generate the signature on a request to refund * a coin into the account of the customer. @@ -766,58 +542,6 @@ struct TALER_RefundConfirmationPS }; -/** - * @brief Message signed by a coin to indicate that the coin should be - * melted. - */ -struct TALER_RefreshMeltCoinAffirmationPS -{ - /** - * Purpose is #TALER_SIGNATURE_WALLET_COIN_MELT. - * Used for an EdDSA signature with the `struct TALER_CoinSpendPublicKeyP`. - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * Which melt commitment is made by the wallet. - */ - struct TALER_RefreshCommitmentP rc GNUNET_PACKED; - - /** - * Hash over the denomination public key used to sign the coin. - */ - struct TALER_DenominationHashP h_denom_pub GNUNET_PACKED; - - /** - * If age commitment was provided during the withdrawal of the coin, this is - * the hash of the age commitment vector. It must be all zeroes if no age - * commitment was provided. - */ - struct TALER_AgeCommitmentHash h_age_commitment GNUNET_PACKED; - - /** - * How much of the value of the coin should be melted? This amount - * includes the fees, so the final amount contributed to the melt is - * this value minus the fee for melting the coin. We include the - * fee in what is being signed so that we can verify a reserve's - * remaining total balance without needing to access the respective - * denomination key information each time. - */ - struct TALER_AmountNBO amount_with_fee; - - /** - * Melting fee charged by the exchange. This must match the Exchange's - * denomination key's melting fee. If the client puts in an invalid - * melting fee (too high or too low) that does not match the Exchange's - * denomination key, the melting operation is invalid and will be - * rejected by the exchange. The @e amount_with_fee minus the @e - * melt_fee is the amount that will be credited to the melting - * session. - */ - struct TALER_AmountNBO melt_fee; -}; - - /** * @brief Format of the block signed by the Exchange in response to a successful * "/refresh/melt" request. Hereby the exchange affirms that all of the @@ -846,51 +570,6 @@ struct TALER_RefreshMeltConfirmationPS }; -/** - * @brief Information about a signing key of the exchange. Signing keys are used - * to sign exchange messages other than coins, i.e. to confirm that a - * deposit was successful or that a refresh was accepted. - */ -struct TALER_ExchangeSigningKeyValidityPS -{ - - /** - * Purpose is #TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY. - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * When does this signing key begin to be valid? - */ - struct GNUNET_TIME_TimestampNBO start; - - /** - * When does this signing key expire? Note: This is currently when - * the Exchange will definitively stop using it. Signatures made with - * the key remain valid until @e end. When checking validity periods, - * clients should allow for some overlap between keys and tolerate - * the use of either key during the overlap time (due to the - * possibility of clock skew). - */ - struct GNUNET_TIME_TimestampNBO expire; - - /** - * When do signatures with this signing key become invalid? After - * this point, these signatures cannot be used in (legal) disputes - * anymore, as the Exchange is then allowed to destroy its side of the - * evidence. @e end is expected to be significantly larger than @e - * expire (by a year or more). - */ - struct GNUNET_TIME_TimestampNBO end; - - /** - * The public online signing key that the exchange will use - * between @e start and @e expire. - */ - struct TALER_ExchangePublicKeyP signkey_pub; -}; - - /** * @brief Signature made by the exchange over the full set of keys, used * to detect cheating exchanges that give out different sets to @@ -943,128 +622,47 @@ struct TALER_ExchangeAccountSetupSuccessPS /** - * @brief Signature made by the exchange offline key over the information of - * an auditor to be added to the exchange's set of auditors. + * @brief Information about a signing key of the exchange. Signing keys are used + * to sign exchange messages other than coins, i.e. to confirm that a + * deposit was successful or that a refresh was accepted. */ -struct TALER_MasterAddAuditorPS +struct TALER_ExchangeSigningKeyValidityPS { /** - * Purpose is #TALER_SIGNATURE_MASTER_ADD_AUDITOR. Signed - * by a `struct TALER_MasterPublicKeyP` using EdDSA. + * Purpose is #TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY. */ struct GNUNET_CRYPTO_EccSignaturePurpose purpose; /** - * Time of the change. + * When does this signing key begin to be valid? */ - struct GNUNET_TIME_TimestampNBO start_date; + struct GNUNET_TIME_TimestampNBO start; /** - * Public key of the auditor. + * When does this signing key expire? Note: This is currently when + * the Exchange will definitively stop using it. Signatures made with + * the key remain valid until @e end. When checking validity periods, + * clients should allow for some overlap between keys and tolerate + * the use of either key during the overlap time (due to the + * possibility of clock skew). */ - struct TALER_AuditorPublicKeyP auditor_pub; + struct GNUNET_TIME_TimestampNBO expire; /** - * Hash over the auditor's URL. + * When do signatures with this signing key become invalid? After + * this point, these signatures cannot be used in (legal) disputes + * anymore, as the Exchange is then allowed to destroy its side of the + * evidence. @e end is expected to be significantly larger than @e + * expire (by a year or more). */ - struct GNUNET_HashCode h_auditor_url GNUNET_PACKED; -}; - - -/** - * @brief Signature made by the exchange offline key over the information of - * an auditor to be removed from the exchange's set of auditors. - */ -struct TALER_MasterDelAuditorPS -{ + struct GNUNET_TIME_TimestampNBO end; /** - * Purpose is #TALER_SIGNATURE_MASTER_DEL_AUDITOR. Signed - * by a `struct TALER_MasterPublicKeyP` using EdDSA. + * The public online signing key that the exchange will use + * between @e start and @e expire. */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * Time of the change. - */ - struct GNUNET_TIME_TimestampNBO end_date; - - /** - * Public key of the auditor. - */ - struct TALER_AuditorPublicKeyP auditor_pub; - -}; - - -/** - * @brief Signature made by the exchange offline key over the information of - * a payto:// URI to be added to the exchange's set of active wire accounts. - */ -struct TALER_MasterAddWirePS -{ - - /** - * Purpose is #TALER_SIGNATURE_MASTER_ADD_WIRE. Signed - * by a `struct TALER_MasterPublicKeyP` using EdDSA. - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * Time of the change. - */ - struct GNUNET_TIME_TimestampNBO start_date; - - /** - * Hash over the exchange's payto URI. - */ - struct TALER_PaytoHashP h_payto GNUNET_PACKED; -}; - - -/** - * @brief Signature made by the exchange offline key over the information of - * a wire method to be removed to the exchange's set of active accounts. - */ -struct TALER_MasterDelWirePS -{ - - /** - * Purpose is #TALER_SIGNATURE_MASTER_DEL_WIRE. Signed - * by a `struct TALER_MasterPublicKeyP` using EdDSA. - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * Time of the change. - */ - struct GNUNET_TIME_TimestampNBO end_date; - - /** - * Hash over the exchange's payto URI. - */ - struct TALER_PaytoHashP h_payto GNUNET_PACKED; - -}; - - -/* - * @brief Signature made by the exchange offline key over the - * configuration of an extension. - */ -struct TALER_MasterExtensionConfigurationPS -{ - /** - * Purpose is #TALER_SIGNATURE_MASTER_EXTENSION. Signed - * by a `struct TALER_MasterPublicKeyP` using EdDSA. - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * Hash of the JSON object that represents the configuration of an extension. - */ - struct TALER_ExtensionConfigHashP h_config GNUNET_PACKED; + struct TALER_ExchangePublicKeyP signkey_pub; }; @@ -1228,183 +826,6 @@ struct TALER_ExchangeKeyValidityPS }; -/** - * @brief Information signed by the exchange's master - * key affirming the IBAN details for the exchange. - */ -struct TALER_MasterWireDetailsPS -{ - - /** - * Purpose is #TALER_SIGNATURE_MASTER_WIRE_DETAILS. - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * Hash over the account holder's payto:// URL. - */ - struct TALER_PaytoHashP h_wire_details GNUNET_PACKED; - -}; - - -/** - * @brief Information signed by the exchange's master - * key affirming the IBAN details for the exchange. - */ -struct TALER_MerchantWireDetailsPS -{ - - /** - * Purpose is #TALER_SIGNATURE_MERCHANT_WIRE_DETAILS. - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * Salted hash over the account holder's payto:// URL and - * the salt, as done by #TALER_merchant_wire_signature_hash(). - */ - struct TALER_MerchantWireHashP h_wire_details GNUNET_PACKED; - -}; - - -/** - * @brief Information signed by the exchange's master - * key stating the wire fee to be paid per wire transfer. - */ -struct TALER_MasterWireFeePS -{ - - /** - * Purpose is #TALER_SIGNATURE_MASTER_WIRE_FEES. - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * Hash over the wire method (yes, H("x-taler-bank") or H("iban")), in lower - * case, including 0-terminator. Used to uniquely identify which - * wire method these fees apply to. - */ - struct GNUNET_HashCode h_wire_method; - - /** - * Start date when the fee goes into effect. - */ - struct GNUNET_TIME_TimestampNBO start_date; - - /** - * End date when the fee stops being in effect (exclusive) - */ - struct GNUNET_TIME_TimestampNBO end_date; - - /** - * Fees charged for wire transfers using the - * given wire method. - */ - struct TALER_WireFeeSetNBOP fees; - -}; - - -/** - * Global fees charged by the exchange independent of - * denomination or wire method. - */ -struct TALER_MasterGlobalFeePS -{ - - /** - * Purpose is #TALER_SIGNATURE_MASTER_GLOBAL_FEES. - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * Start date when the fee goes into effect. - */ - struct GNUNET_TIME_TimestampNBO start_date; - - /** - * End date when the fee stops being in effect (exclusive) - */ - struct GNUNET_TIME_TimestampNBO end_date; - - /** - * How long does an exchange keep a purse around after a purse - * has expired (or been successfully merged)? A 'GET' request - * for a purse will succeed until the purse expiration time - * plus this value. - */ - struct GNUNET_TIME_RelativeNBO purse_timeout; - - /** - * How long does the exchange promise to keep funds - * an account for which the KYC has never happened - * after a purse was merged into an account? Basically, - * after this time funds in an account without KYC are - * forfeit. - */ - struct GNUNET_TIME_RelativeNBO kyc_timeout; - - /** - * How long will the exchange preserve the account history? After an - * account was deleted/closed, the exchange will retain the account history - * for legal reasons until this time. - */ - struct GNUNET_TIME_RelativeNBO history_expiration; - - /** - * Fee charged to the merchant per wire transfer. - */ - struct TALER_GlobalFeeSetNBOP fees; - - /** - * Number of concurrent purses that any - * account holder is allowed to create without having - * to pay the @e purse_fee. Here given in NBO. - */ - uint32_t purse_account_limit; - - -}; - - -/** - * @brief Message confirming that a denomination key was revoked. - */ -struct TALER_MasterDenominationKeyRevocationPS -{ - /** - * Purpose is #TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED. - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * Hash of the denomination key. - */ - struct TALER_DenominationHashP h_denom_pub; - -}; - - -/** - * @brief Message confirming that an exchange online signing key was revoked. - */ -struct TALER_MasterSigningKeyRevocationPS -{ - /** - * Purpose is #TALER_SIGNATURE_MASTER_SIGNING_KEY_REVOKED. - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * The exchange's public key. - */ - struct TALER_ExchangePublicKeyP exchange_pub; - -}; - - /** * @brief Format used to generate the signature on a request to obtain * the wire transfer identifier associated with a deposit. @@ -1602,32 +1023,6 @@ struct TALER_ConfirmWirePS }; -/** - * Signed data to request that a coin should be refunded as part of - * the "emergency" /recoup protocol. The refund will go back to the bank - * account that created the reserve. - */ -struct TALER_RecoupRequestPS -{ - /** - * Purpose is #TALER_SIGNATURE_WALLET_COIN_RECOUP - * or #TALER_SIGNATURE_WALLET_COIN_RECOUP_REFRESH. - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * Hash of the (revoked) denomination public key of the coin. - */ - struct TALER_DenominationHashP h_denom_pub; - - /** - * Blinding factor that was used to withdraw the coin. - */ - union TALER_DenominationBlindingKeyP coin_blind; - -}; - - /** * Response by which the exchange affirms that it will * refund a coin as part of the emergency /recoup @@ -1804,53 +1199,6 @@ struct TALER_ReserveCloseConfirmationPS }; -/** - * Used by the merchant to confirm to the frontend that - * the user did a payment replay with the current browser session. - */ -struct TALER_MerchantPaySessionSigPS -{ - /** - * Set to #TALER_SIGNATURE_MERCHANT_PAY_SESSION. - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * Hashed order id. - * Hashed without the 0-termination. - */ - struct GNUNET_HashCode h_order_id GNUNET_PACKED; - - /** - * Hashed session id. - * Hashed without the 0-termination. - */ - struct GNUNET_HashCode h_session_id GNUNET_PACKED; - -}; - -/** - * Used for attestation of a particular age - */ -struct TALER_AgeAttestationPS -{ - /** - * Purpose must be #TALER_SIGNATURE_WALLET_AGE_ATTESTATION. - */ - struct GNUNET_CRYPTO_EccSignaturePurpose purpose; - - /** - * Age mask that defines the underlying age groups - */ - struct TALER_AgeMask mask; - - /** - * The particular age that this attestation is for - */ - uint8_t age; -}; - - GNUNET_NETWORK_STRUCT_END #endif diff --git a/src/util/age_restriction.c b/src/util/age_restriction.c index 92143ad09..a9e066c85 100644 --- a/src/util/age_restriction.c +++ b/src/util/age_restriction.c @@ -217,6 +217,28 @@ TALER_age_commitment_derive ( } +/** + * Used for attestation of a particular age + */ +struct TALER_AgeAttestationPS +{ + /** + * Purpose must be #TALER_SIGNATURE_WALLET_AGE_ATTESTATION. + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * Age mask that defines the underlying age groups + */ + struct TALER_AgeMask mask; + + /** + * The particular age that this attestation is for + */ + uint8_t age; +}; + + enum GNUNET_GenericReturnValue TALER_age_commitment_attest ( const struct TALER_AgeCommitmentProof *cp, diff --git a/src/util/crypto_wire.c b/src/util/crypto_wire.c index 93a952983..aa504b81e 100644 --- a/src/util/crypto_wire.c +++ b/src/util/crypto_wire.c @@ -23,45 +23,6 @@ #include "taler_signatures.h" -enum GNUNET_GenericReturnValue -TALER_exchange_wire_signature_check ( - const char *payto_uri, - const struct TALER_MasterPublicKeyP *master_pub, - const struct TALER_MasterSignatureP *master_sig) -{ - struct TALER_MasterWireDetailsPS wd = { - .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_WIRE_DETAILS), - .purpose.size = htonl (sizeof (wd)) - }; - - TALER_payto_hash (payto_uri, - &wd.h_wire_details); - return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_WIRE_DETAILS, - &wd, - &master_sig->eddsa_signature, - &master_pub->eddsa_pub); -} - - -void -TALER_exchange_wire_signature_make ( - const char *payto_uri, - const struct TALER_MasterPrivateKeyP *master_priv, - struct TALER_MasterSignatureP *master_sig) -{ - struct TALER_MasterWireDetailsPS wd = { - .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_WIRE_DETAILS), - .purpose.size = htonl (sizeof (wd)) - }; - - TALER_payto_hash (payto_uri, - &wd.h_wire_details); - GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv, - &wd, - &master_sig->eddsa_signature); -} - - void TALER_merchant_wire_signature_hash (const char *payto_uri, const struct TALER_WireSaltP *salt, @@ -80,47 +41,4 @@ TALER_merchant_wire_signature_hash (const char *payto_uri, } -enum GNUNET_GenericReturnValue -TALER_merchant_wire_signature_check ( - const char *payto_uri, - const struct TALER_WireSaltP *salt, - const struct TALER_MerchantPublicKeyP *merch_pub, - const struct TALER_MerchantSignatureP *merch_sig) -{ - struct TALER_MerchantWireDetailsPS wd = { - .purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_WIRE_DETAILS), - .purpose.size = htonl (sizeof (wd)) - }; - - TALER_merchant_wire_signature_hash (payto_uri, - salt, - &wd.h_wire_details); - return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_WIRE_DETAILS, - &wd, - &merch_sig->eddsa_sig, - &merch_pub->eddsa_pub); -} - - -void -TALER_merchant_wire_signature_make ( - const char *payto_uri, - const struct TALER_WireSaltP *salt, - const struct TALER_MerchantPrivateKeyP *merch_priv, - struct TALER_MerchantSignatureP *merch_sig) -{ - struct TALER_MerchantWireDetailsPS wd = { - .purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_WIRE_DETAILS), - .purpose.size = htonl (sizeof (wd)) - }; - - TALER_merchant_wire_signature_hash (payto_uri, - salt, - &wd.h_wire_details); - GNUNET_CRYPTO_eddsa_sign (&merch_priv->eddsa_priv, - &wd, - &merch_sig->eddsa_sig); -} - - /* end of crypto_wire.c */ diff --git a/src/util/merchant_signatures.c b/src/util/merchant_signatures.c index 4cc00a6c7..4223b82ba 100644 --- a/src/util/merchant_signatures.c +++ b/src/util/merchant_signatures.c @@ -23,6 +23,42 @@ #include "taler_signatures.h" +/** + * @brief Format used to generate the signature on a request to refund + * a coin into the account of the customer. + */ +struct TALER_RefundRequestPS +{ + /** + * Purpose must be #TALER_SIGNATURE_MERCHANT_REFUND. + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * Hash over the proposal data to identify the contract + * which is being refunded. + */ + struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED; + + /** + * The coin's public key. This is the value that must have been + * signed (blindly) by the Exchange. + */ + struct TALER_CoinSpendPublicKeyP coin_pub; + + /** + * Merchant-generated transaction ID for the refund. + */ + uint64_t rtransaction_id GNUNET_PACKED; + + /** + * Amount to be refunded, including refund fee charged by the + * exchange to the customer. + */ + struct TALER_AmountNBO refund_amount; +}; + + void TALER_merchant_refund_sign ( const struct TALER_CoinSpendPublicKeyP *coin_pub, @@ -75,4 +111,68 @@ TALER_merchant_refund_verify ( } +/** + * @brief Information signed by the exchange's master + * key affirming the IBAN details for the exchange. + */ +struct TALER_MerchantWireDetailsPS +{ + + /** + * Purpose is #TALER_SIGNATURE_MERCHANT_WIRE_DETAILS. + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * Salted hash over the account holder's payto:// URL and + * the salt, as done by #TALER_merchant_wire_signature_hash(). + */ + struct TALER_MerchantWireHashP h_wire_details GNUNET_PACKED; + +}; + + +enum GNUNET_GenericReturnValue +TALER_merchant_wire_signature_check ( + const char *payto_uri, + const struct TALER_WireSaltP *salt, + const struct TALER_MerchantPublicKeyP *merch_pub, + const struct TALER_MerchantSignatureP *merch_sig) +{ + struct TALER_MerchantWireDetailsPS wd = { + .purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_WIRE_DETAILS), + .purpose.size = htonl (sizeof (wd)) + }; + + TALER_merchant_wire_signature_hash (payto_uri, + salt, + &wd.h_wire_details); + return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_WIRE_DETAILS, + &wd, + &merch_sig->eddsa_sig, + &merch_pub->eddsa_pub); +} + + +void +TALER_merchant_wire_signature_make ( + const char *payto_uri, + const struct TALER_WireSaltP *salt, + const struct TALER_MerchantPrivateKeyP *merch_priv, + struct TALER_MerchantSignatureP *merch_sig) +{ + struct TALER_MerchantWireDetailsPS wd = { + .purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_WIRE_DETAILS), + .purpose.size = htonl (sizeof (wd)) + }; + + TALER_merchant_wire_signature_hash (payto_uri, + salt, + &wd.h_wire_details); + GNUNET_CRYPTO_eddsa_sign (&merch_priv->eddsa_priv, + &wd, + &merch_sig->eddsa_sig); +} + + /* end of merchant_signatures.c */ diff --git a/src/util/offline_signatures.c b/src/util/offline_signatures.c index 1085ac151..c11e20f46 100644 --- a/src/util/offline_signatures.c +++ b/src/util/offline_signatures.c @@ -23,6 +23,36 @@ #include "taler_signatures.h" +/** + * @brief Signature made by the exchange offline key over the information of + * an auditor to be added to the exchange's set of auditors. + */ +struct TALER_MasterAddAuditorPS +{ + + /** + * Purpose is #TALER_SIGNATURE_MASTER_ADD_AUDITOR. Signed + * by a `struct TALER_MasterPublicKeyP` using EdDSA. + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * Time of the change. + */ + struct GNUNET_TIME_TimestampNBO start_date; + + /** + * Public key of the auditor. + */ + struct TALER_AuditorPublicKeyP auditor_pub; + + /** + * Hash over the auditor's URL. + */ + struct GNUNET_HashCode h_auditor_url GNUNET_PACKED; +}; + + void TALER_exchange_offline_auditor_add_sign ( const struct TALER_AuditorPublicKeyP *auditor_pub, @@ -73,6 +103,32 @@ TALER_exchange_offline_auditor_add_verify ( } +/** + * @brief Signature made by the exchange offline key over the information of + * an auditor to be removed from the exchange's set of auditors. + */ +struct TALER_MasterDelAuditorPS +{ + + /** + * Purpose is #TALER_SIGNATURE_MASTER_DEL_AUDITOR. Signed + * by a `struct TALER_MasterPublicKeyP` using EdDSA. + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * Time of the change. + */ + struct GNUNET_TIME_TimestampNBO end_date; + + /** + * Public key of the auditor. + */ + struct TALER_AuditorPublicKeyP auditor_pub; + +}; + + void TALER_exchange_offline_auditor_del_sign ( const struct TALER_AuditorPublicKeyP *auditor_pub, @@ -115,6 +171,24 @@ TALER_exchange_offline_auditor_del_verify ( } +/** + * @brief Message confirming that a denomination key was revoked. + */ +struct TALER_MasterDenominationKeyRevocationPS +{ + /** + * Purpose is #TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED. + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * Hash of the denomination key. + */ + struct TALER_DenominationHashP h_denom_pub; + +}; + + void TALER_exchange_offline_denomination_revoke_sign ( const struct TALER_DenominationHashP *h_denom_pub, @@ -154,6 +228,24 @@ TALER_exchange_offline_denomination_revoke_verify ( } +/** + * @brief Message confirming that an exchange online signing key was revoked. + */ +struct TALER_MasterSigningKeyRevocationPS +{ + /** + * Purpose is #TALER_SIGNATURE_MASTER_SIGNING_KEY_REVOKED. + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * The exchange's public key. + */ + struct TALER_ExchangePublicKeyP exchange_pub; + +}; + + void TALER_exchange_offline_signkey_revoke_sign ( const struct TALER_ExchangePublicKeyP *exchange_pub, @@ -320,6 +412,31 @@ TALER_exchange_offline_denom_validity_verify ( } +/** + * @brief Signature made by the exchange offline key over the information of + * a payto:// URI to be added to the exchange's set of active wire accounts. + */ +struct TALER_MasterAddWirePS +{ + + /** + * Purpose is #TALER_SIGNATURE_MASTER_ADD_WIRE. Signed + * by a `struct TALER_MasterPublicKeyP` using EdDSA. + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * Time of the change. + */ + struct GNUNET_TIME_TimestampNBO start_date; + + /** + * Hash over the exchange's payto URI. + */ + struct TALER_PaytoHashP h_payto GNUNET_PACKED; +}; + + void TALER_exchange_offline_wire_add_sign ( const char *payto_uri, @@ -365,6 +482,32 @@ TALER_exchange_offline_wire_add_verify ( } +/** + * @brief Signature made by the exchange offline key over the information of + * a wire method to be removed to the exchange's set of active accounts. + */ +struct TALER_MasterDelWirePS +{ + + /** + * Purpose is #TALER_SIGNATURE_MASTER_DEL_WIRE. Signed + * by a `struct TALER_MasterPublicKeyP` using EdDSA. + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * Time of the change. + */ + struct GNUNET_TIME_TimestampNBO end_date; + + /** + * Hash over the exchange's payto URI. + */ + struct TALER_PaytoHashP h_payto GNUNET_PACKED; + +}; + + void TALER_exchange_offline_wire_del_sign ( const char *payto_uri, @@ -410,6 +553,44 @@ TALER_exchange_offline_wire_del_verify ( } +/** + * @brief Information signed by the exchange's master + * key stating the wire fee to be paid per wire transfer. + */ +struct TALER_MasterWireFeePS +{ + + /** + * Purpose is #TALER_SIGNATURE_MASTER_WIRE_FEES. + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * Hash over the wire method (yes, H("x-taler-bank") or H("iban")), in lower + * case, including 0-terminator. Used to uniquely identify which + * wire method these fees apply to. + */ + struct GNUNET_HashCode h_wire_method; + + /** + * Start date when the fee goes into effect. + */ + struct GNUNET_TIME_TimestampNBO start_date; + + /** + * End date when the fee stops being in effect (exclusive) + */ + struct GNUNET_TIME_TimestampNBO end_date; + + /** + * Fees charged for wire transfers using the + * given wire method. + */ + struct TALER_WireFeeSetNBOP fees; + +}; + + void TALER_exchange_offline_wire_fee_sign ( const char *payment_method, @@ -466,6 +647,68 @@ TALER_exchange_offline_wire_fee_verify ( } +/** + * Global fees charged by the exchange independent of + * denomination or wire method. + */ +struct TALER_MasterGlobalFeePS +{ + + /** + * Purpose is #TALER_SIGNATURE_MASTER_GLOBAL_FEES. + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * Start date when the fee goes into effect. + */ + struct GNUNET_TIME_TimestampNBO start_date; + + /** + * End date when the fee stops being in effect (exclusive) + */ + struct GNUNET_TIME_TimestampNBO end_date; + + /** + * How long does an exchange keep a purse around after a purse + * has expired (or been successfully merged)? A 'GET' request + * for a purse will succeed until the purse expiration time + * plus this value. + */ + struct GNUNET_TIME_RelativeNBO purse_timeout; + + /** + * How long does the exchange promise to keep funds + * an account for which the KYC has never happened + * after a purse was merged into an account? Basically, + * after this time funds in an account without KYC are + * forfeit. + */ + struct GNUNET_TIME_RelativeNBO kyc_timeout; + + /** + * How long will the exchange preserve the account history? After an + * account was deleted/closed, the exchange will retain the account history + * for legal reasons until this time. + */ + struct GNUNET_TIME_RelativeNBO history_expiration; + + /** + * Fee charged to the merchant per wire transfer. + */ + struct TALER_GlobalFeeSetNBOP fees; + + /** + * Number of concurrent purses that any + * account holder is allowed to create without having + * to pay the @e purse_fee. Here given in NBO. + */ + uint32_t purse_account_limit; + + +}; + + void TALER_exchange_offline_global_fee_sign ( struct GNUNET_TIME_Timestamp start_time, @@ -530,6 +773,25 @@ TALER_exchange_offline_global_fee_verify ( } +/** + * @brief Signature made by the exchange offline key over the + * configuration of an extension. + */ +struct TALER_MasterExtensionConfigurationPS +{ + /** + * Purpose is #TALER_SIGNATURE_MASTER_EXTENSION. Signed + * by a `struct TALER_MasterPublicKeyP` using EdDSA. + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * Hash of the JSON object that represents the configuration of an extension. + */ + struct TALER_ExtensionConfigHashP h_config GNUNET_PACKED; +}; + + void TALER_exchange_offline_extension_config_hash_sign ( const struct TALER_ExtensionConfigHashP *h_config, @@ -567,4 +829,63 @@ TALER_exchange_offline_extension_config_hash_verify ( } +/** + * @brief Information signed by the exchange's master + * key affirming the IBAN details for the exchange. + */ +struct TALER_MasterWireDetailsPS +{ + + /** + * Purpose is #TALER_SIGNATURE_MASTER_WIRE_DETAILS. + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * Hash over the account holder's payto:// URL. + */ + struct TALER_PaytoHashP h_wire_details GNUNET_PACKED; + +}; + + +enum GNUNET_GenericReturnValue +TALER_exchange_wire_signature_check ( + const char *payto_uri, + const struct TALER_MasterPublicKeyP *master_pub, + const struct TALER_MasterSignatureP *master_sig) +{ + struct TALER_MasterWireDetailsPS wd = { + .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_WIRE_DETAILS), + .purpose.size = htonl (sizeof (wd)) + }; + + TALER_payto_hash (payto_uri, + &wd.h_wire_details); + return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_WIRE_DETAILS, + &wd, + &master_sig->eddsa_signature, + &master_pub->eddsa_pub); +} + + +void +TALER_exchange_wire_signature_make ( + const char *payto_uri, + const struct TALER_MasterPrivateKeyP *master_priv, + struct TALER_MasterSignatureP *master_sig) +{ + struct TALER_MasterWireDetailsPS wd = { + .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_WIRE_DETAILS), + .purpose.size = htonl (sizeof (wd)) + }; + + TALER_payto_hash (payto_uri, + &wd.h_wire_details); + GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv, + &wd, + &master_sig->eddsa_signature); +} + + /* end of offline_signatures.c */ diff --git a/src/util/wallet_signatures.c b/src/util/wallet_signatures.c index ef8870442..30903c6b7 100644 --- a/src/util/wallet_signatures.c +++ b/src/util/wallet_signatures.c @@ -23,6 +23,93 @@ #include "taler_signatures.h" +/** + * @brief Format used to generate the signature on a request to deposit + * a coin into the account of a merchant. + */ +struct TALER_DepositRequestPS +{ + /** + * Purpose must be #TALER_SIGNATURE_WALLET_COIN_DEPOSIT. + * Used for an EdDSA signature with the `struct TALER_CoinSpendPublicKeyP`. + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * Hash over the contract for which this deposit is made. + */ + struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED; + + /** + * Hash over the age commitment that went into the coin. Maybe all zero, if + * age commitment isn't applicable to the denomination. + */ + struct TALER_AgeCommitmentHash h_age_commitment GNUNET_PACKED; + + /** + * Hash over extension attributes shared with the exchange. + */ + struct TALER_ExtensionContractHashP h_extensions GNUNET_PACKED; + + /** + * Hash over the wiring information of the merchant. + */ + struct TALER_MerchantWireHashP h_wire GNUNET_PACKED; + + /** + * Hash over the denomination public key used to sign the coin. + */ + struct TALER_DenominationHashP h_denom_pub GNUNET_PACKED; + + /** + * Time when this request was generated. Used, for example, to + * assess when (roughly) the income was achieved for tax purposes. + * Note that the Exchange will only check that the timestamp is not "too + * far" into the future (i.e. several days). The fact that the + * timestamp falls within the validity period of the coin's + * denomination key is irrelevant for the validity of the deposit + * request, as obviously the customer and merchant could conspire to + * set any timestamp. Also, the Exchange must accept very old deposit + * requests, as the merchant might have been unable to transmit the + * deposit request in a timely fashion (so back-dating is not + * prevented). + */ + struct GNUNET_TIME_TimestampNBO wallet_timestamp; + + /** + * How much time does the merchant have to issue a refund request? + * Zero if refunds are not allowed. After this time, the coin + * cannot be refunded. + */ + struct GNUNET_TIME_TimestampNBO refund_deadline; + + /** + * Amount to be deposited, including deposit fee charged by the + * exchange. This is the total amount that the coin's value at the exchange + * will be reduced by. + */ + struct TALER_AmountNBO amount_with_fee; + + /** + * Depositing fee charged by the exchange. This must match the Exchange's + * denomination key's depositing fee. If the client puts in an + * invalid deposit fee (too high or too low) that does not match the + * Exchange's denomination key, the deposit operation is invalid and + * will be rejected by the exchange. The @e amount_with_fee minus the + * @e deposit_fee is the amount that will be transferred to the + * account identified by @e h_wire. + */ + struct TALER_AmountNBO deposit_fee; + + /** + * The Merchant's public key. Allows the merchant to later refund + * the transaction or to inquire about the wire transfer identifier. + */ + struct TALER_MerchantPublicKeyP merchant; + +}; + + void TALER_wallet_deposit_sign ( const struct TALER_Amount *amount, @@ -116,6 +203,41 @@ TALER_wallet_deposit_verify ( } +/** + * @brief Format used for to allow the wallet to authenticate + * link data provided by the exchange. + */ +struct TALER_LinkDataPS +{ + + /** + * Purpose must be #TALER_SIGNATURE_WALLET_COIN_LINK. + * Used with an EdDSA signature of a `struct TALER_CoinPublicKeyP`. + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * Hash of the denomination public key of the new coin. + */ + struct TALER_DenominationHashP h_denom_pub; + + /** + * Transfer public key (for which the private key was not revealed) + */ + struct TALER_TransferPublicKeyP transfer_pub; + + /** + * Hash of the age commitment, if applicable. Can be all zero + */ + struct TALER_AgeCommitmentHash h_age_commitment; + + /** + * Hash of the blinded new coin. + */ + struct TALER_BlindedCoinHashP coin_envelope_hash; +}; + + void TALER_wallet_link_sign (const struct TALER_DenominationHashP *h_denom_pub, const struct TALER_TransferPublicKeyP *transfer_pub, @@ -161,6 +283,32 @@ TALER_wallet_link_verify ( } +/** + * Signed data to request that a coin should be refunded as part of + * the "emergency" /recoup protocol. The refund will go back to the bank + * account that created the reserve. + */ +struct TALER_RecoupRequestPS +{ + /** + * Purpose is #TALER_SIGNATURE_WALLET_COIN_RECOUP + * or #TALER_SIGNATURE_WALLET_COIN_RECOUP_REFRESH. + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * Hash of the (revoked) denomination public key of the coin. + */ + struct TALER_DenominationHashP h_denom_pub; + + /** + * Blinding factor that was used to withdraw the coin. + */ + union TALER_DenominationBlindingKeyP coin_blind; + +}; + + enum GNUNET_GenericReturnValue TALER_wallet_recoup_verify ( const struct TALER_DenominationHashP *h_denom_pub, @@ -243,6 +391,58 @@ TALER_wallet_recoup_refresh_sign ( } +/** + * @brief Message signed by a coin to indicate that the coin should be + * melted. + */ +struct TALER_RefreshMeltCoinAffirmationPS +{ + /** + * Purpose is #TALER_SIGNATURE_WALLET_COIN_MELT. + * Used for an EdDSA signature with the `struct TALER_CoinSpendPublicKeyP`. + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * Which melt commitment is made by the wallet. + */ + struct TALER_RefreshCommitmentP rc GNUNET_PACKED; + + /** + * Hash over the denomination public key used to sign the coin. + */ + struct TALER_DenominationHashP h_denom_pub GNUNET_PACKED; + + /** + * If age commitment was provided during the withdrawal of the coin, this is + * the hash of the age commitment vector. It must be all zeroes if no age + * commitment was provided. + */ + struct TALER_AgeCommitmentHash h_age_commitment GNUNET_PACKED; + + /** + * How much of the value of the coin should be melted? This amount + * includes the fees, so the final amount contributed to the melt is + * this value minus the fee for melting the coin. We include the + * fee in what is being signed so that we can verify a reserve's + * remaining total balance without needing to access the respective + * denomination key information each time. + */ + struct TALER_AmountNBO amount_with_fee; + + /** + * Melting fee charged by the exchange. This must match the Exchange's + * denomination key's melting fee. If the client puts in an invalid + * melting fee (too high or too low) that does not match the Exchange's + * denomination key, the melting operation is invalid and will be + * rejected by the exchange. The @e amount_with_fee minus the @e + * melt_fee is the amount that will be credited to the melting + * session. + */ + struct TALER_AmountNBO melt_fee; +}; + + void TALER_wallet_melt_sign ( const struct TALER_Amount *amount_with_fee, @@ -308,6 +508,40 @@ TALER_wallet_melt_verify ( } +/** + * @brief Format used for to generate the signature on a request to withdraw + * coins from a reserve. + */ +struct TALER_WithdrawRequestPS +{ + + /** + * Purpose must be #TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW. + * Used with an EdDSA signature of a `struct TALER_ReservePublicKeyP`. + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * Value of the coin being exchanged (matching the denomination key) + * plus the transaction fee. We include this in what is being + * signed so that we can verify a reserve's remaining total balance + * without needing to access the respective denomination key + * information each time. + */ + struct TALER_AmountNBO amount_with_fee; + + /** + * Hash of the denomination public key for the coin that is withdrawn. + */ + struct TALER_DenominationHashP h_denomination_pub GNUNET_PACKED; + + /** + * Hash of the (blinded) message to be signed by the Exchange. + */ + struct TALER_BlindedCoinHashP h_coin_envelope GNUNET_PACKED; +}; + + void TALER_wallet_withdraw_sign ( const struct TALER_DenominationHashP *h_denom_pub, @@ -373,6 +607,50 @@ TALER_wallet_account_setup_sign ( } +enum GNUNET_GenericReturnValue +TALER_wallet_account_setup_verify ( + const struct TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_ReserveSignatureP *reserve_sig) +{ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose = { + .size = htonl (sizeof (purpose)), + .purpose = htonl (TALER_SIGNATURE_WALLET_ACCOUNT_SETUP) + }; + + return GNUNET_CRYPTO_eddsa_verify_ ( + TALER_SIGNATURE_WALLET_RESERVE_STATUS, + &purpose, + &reserve_sig->eddsa_signature, + &reserve_pub->eddsa_pub); +} + + +/** + * Response by which a wallet requests a full + * reserve history and indicates it is willing + * to pay for it. + */ +struct TALER_ReserveHistoryRequestPS +{ + + /** + * Purpose is #TALER_SIGNATURE_WALLET_RESERVE_HISTORY + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * When did the wallet make the requst. + */ + struct GNUNET_TIME_TimestampNBO request_timestamp; + + /** + * How much does the exchange charge for the history? + */ + struct TALER_AmountNBO history_fee; + +}; + + enum GNUNET_GenericReturnValue TALER_wallet_reserve_history_verify ( const struct GNUNET_TIME_Timestamp ts, @@ -417,6 +695,25 @@ TALER_wallet_reserve_history_sign ( } +/** + * Response by which a wallet requests an account status. + */ +struct TALER_ReserveStatusRequestPS +{ + + /** + * Purpose is #TALER_SIGNATURE_WALLET_RESERVE_STATUS + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * When did the wallet make the requst. + */ + struct GNUNET_TIME_TimestampNBO request_timestamp; + +}; + + enum GNUNET_GenericReturnValue TALER_wallet_reserve_status_verify ( const struct GNUNET_TIME_Timestamp ts, @@ -455,4 +752,410 @@ TALER_wallet_reserve_status_sign ( } +/** + * Message signed to create a purse (without reserve). + */ +struct TALER_PurseCreatePS +{ + + /** + * Purpose is #TALER_SIGNATURE_WALLET_PURSE_CREATE + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * Time when the purse will expire if still unmerged or unpaid. + */ + struct GNUNET_TIME_TimestampNBO purse_expiration; + + /** + * Total amount (with fees) to be put into the purse. + */ + struct TALER_AmountNBO purse_amount; + + /** + * Contract this purse pays for. + */ + struct TALER_PrivateContractHashP h_contract_terms; + + /** + * Minimum age required for payments into this purse. + */ + uint32_t min_age GNUNET_PACKED; + +}; + + +void +TALER_wallet_purse_create_sign ( + struct GNUNET_TIME_Timestamp purse_expiration, + struct TALER_PrivateContractHashP *h_contract_terms, + uint32_t min_age, + const struct TALER_Amount *amount, + const struct TALER_PursePrivateKeyP *purse_priv, + struct TALER_PurseSignatureP *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, + .min_age = htonl (min_age) + }; + + TALER_amount_hton (&pm.purse_amount, + amount); + GNUNET_CRYPTO_eddsa_sign (&purse_priv->eddsa_priv, + &pm, + &purse_sig->eddsa_signature); +} + + +enum GNUNET_GenericReturnValue +TALER_wallet_purse_create_verify ( + struct GNUNET_TIME_Timestamp purse_expiration, + struct TALER_PrivateContractHashP *h_contract_terms, + uint32_t min_age, + const struct TALER_Amount *amount, + const struct TALER_PursePublicKeyP *purse_pub, + const struct TALER_PurseSignatureP *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, + .min_age = htonl (min_age) + }; + + TALER_amount_hton (&pm.purse_amount, + amount); + return GNUNET_CRYPTO_eddsa_verify ( + TALER_SIGNATURE_WALLET_PURSE_CREATE, + &pm, + &purse_sig->eddsa_signature, + &purse_pub->eddsa_pub); +} + + +void +TALER_wallet_purse_status_sign ( + const struct TALER_PursePrivateKeyP *purse_priv, + struct TALER_PurseSignatureP *purse_sig) +{ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose = { + .size = htonl (sizeof (purpose)), + .purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_STATUS) + }; + + GNUNET_assert (GNUNET_OK == + GNUNET_CRYPTO_eddsa_sign_ (&purse_priv->eddsa_priv, + &purpose, + &purse_sig->eddsa_signature)); +} + + +enum GNUNET_GenericReturnValue +TALER_wallet_purse_status_verify ( + const struct TALER_PursePublicKeyP *purse_pub, + const struct TALER_PurseSignatureP *purse_sig) +{ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose = { + .size = htonl (sizeof (purpose)), + .purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_STATUS) + }; + + return GNUNET_CRYPTO_eddsa_verify_ (TALER_SIGNATURE_WALLET_PURSE_STATUS, + &purpose, + &purse_sig->eddsa_signature, + &purse_pub->eddsa_pub); +} + + +/** + * Message signed to deposit a coin into a purse. + */ +struct TALER_PurseDepositPS +{ + + /** + * Purpose is #TALER_SIGNATURE_WALLET_PURSE_DEPOSIT + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * Amount (with deposit fee) to be deposited into the purse. + */ + struct TALER_AmountNBO coin_amount; + + /** + * Purse to deposit funds into. + */ + struct TALER_PursePublicKeyP purse_pub; + +}; + + +void +TALER_wallet_purse_deposit_sign ( + const struct TALER_PursePublicKeyP *purse_pub, + const struct TALER_Amount *amount, + const struct TALER_CoinSpendPrivateKeyP *coin_priv, + struct TALER_CoinSpendSignatureP *coin_sig) +{ + struct TALER_PurseDepositPS pm = { + .purpose.size = htonl (sizeof (pm)), + .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_DEPOSIT), + .purse_pub = *purse_pub, + }; + + TALER_amount_hton (&pm.coin_amount, + amount); + GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv, + &pm, + &coin_sig->eddsa_signature); +} + + +enum GNUNET_GenericReturnValue +TALER_wallet_purse_deposit_verify ( + const struct TALER_PursePublicKeyP *purse_pub, + const struct TALER_Amount *amount, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_CoinSpendSignatureP *coin_sig) +{ + struct TALER_PurseDepositPS pm = { + .purpose.size = htonl (sizeof (pm)), + .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_DEPOSIT), + .purse_pub = *purse_pub, + }; + + TALER_amount_hton (&pm.coin_amount, + amount); + return GNUNET_CRYPTO_eddsa_verify ( + TALER_SIGNATURE_WALLET_PURSE_DEPOSIT, + &pm, + &coin_sig->eddsa_signature, + &coin_pub->eddsa_pub); +} + + +/** + * Message signed to merge a purse into a reserve. + */ +struct TALER_PurseMergePS +{ + + /** + * Purpose is #TALER_SIGNATURE_WALLET_PURSE_MERGE + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * Time when the purse is merged into the reserve. + */ + struct GNUNET_TIME_TimestampNBO merge_timestamp; + + /** + * Which reserve should the purse be merged with. + * Hash of the reserve's payto:// URI. + */ + struct TALER_PaytoHashP h_payto; + +}; + + +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) +{ + 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), + }; + + TALER_payto_hash (reserve_url, + &pm.h_payto); + GNUNET_CRYPTO_eddsa_sign (&purse_priv->eddsa_priv, + &pm, + &purse_sig->eddsa_signature); +} + + +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) +{ + 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), + }; + + TALER_payto_hash (reserve_url, + &pm.h_payto); + return GNUNET_CRYPTO_eddsa_verify ( + TALER_SIGNATURE_WALLET_ACCOUNT_MERGE, + &pm, + &purse_sig->eddsa_signature, + &purse_pub->eddsa_pub); +} + + +/** + * Message signed by account to merge a purse into a reserve. + */ +struct TALER_AccountMergePS +{ + + /** + * Purpose is #TALER_SIGNATURE_WALLET_ACCOUNT_MERGE + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * Time when the purse will expire if still unmerged or unpaid. + */ + struct GNUNET_TIME_TimestampNBO purse_expiration; + + /** + * Total amount (with fees) to be put into the purse. + */ + 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. + */ + struct TALER_PrivateContractHashP h_contract_terms; + + /** + * Purse to merge. + */ + struct TALER_PursePublicKeyP purse_pub; + + /** + * Time when the purse is merged into the reserve. + */ + struct GNUNET_TIME_TimestampNBO merge_timestamp; + + /** + * Minimum age required for payments into this purse. + */ + uint32_t min_age GNUNET_PACKED; +}; + + +void +TALER_wallet_account_merge_sign ( + const char *reserve_url, + struct GNUNET_TIME_Timestamp merge_timestamp, + const struct TALER_PursePublicKeyP *purse_pub, + struct GNUNET_TIME_Timestamp purse_expiration, + struct TALER_PrivateContractHashP *h_contract_terms, + const struct TALER_Amount *amount, + uint32_t min_age, + const struct TALER_ReservePrivateKeyP *reserve_priv, + struct TALER_ReserveSignatureP *reserve_sig) +{ + struct TALER_AccountMergePS pm = { + .purpose.size = htonl (sizeof (pm)), + .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_ACCOUNT_MERGE), + .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp), + .purse_pub = *purse_pub, + .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration), + .h_contract_terms = *h_contract_terms, + .min_age = htonl (min_age) + }; + + 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); +} + + +enum GNUNET_GenericReturnValue +TALER_wallet_account_merge_verify ( + const char *reserve_url, + struct GNUNET_TIME_Timestamp merge_timestamp, + const struct TALER_PursePublicKeyP *purse_pub, + struct GNUNET_TIME_Timestamp purse_expiration, + struct TALER_PrivateContractHashP *h_contract_terms, + const struct TALER_Amount *amount, + uint32_t min_age, + const struct TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_ReserveSignatureP *reserve_sig) +{ + struct TALER_AccountMergePS pm = { + .purpose.size = htonl (sizeof (pm)), + .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_ACCOUNT_MERGE), + .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp), + .purse_pub = *purse_pub, + .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration), + .h_contract_terms = *h_contract_terms, + .min_age = htonl (min_age) + }; + + 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, + &reserve_sig->eddsa_signature, + &reserve_pub->eddsa_pub); +} + + +void +TALER_wallet_account_close_sign ( + const struct TALER_ReservePrivateKeyP *reserve_priv, + struct TALER_ReserveSignatureP *reserve_sig) +{ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose = { + .size = htonl (sizeof (purpose)), + .purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_CLOSE) + }; + + GNUNET_assert (GNUNET_OK == + GNUNET_CRYPTO_eddsa_sign_ (&reserve_priv->eddsa_priv, + &purpose, + &reserve_sig->eddsa_signature)); +} + + +enum GNUNET_GenericReturnValue +TALER_wallet_account_close_verify ( + const struct TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_ReserveSignatureP *reserve_sig) +{ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose = { + .size = htonl (sizeof (purpose)), + .purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_CLOSE) + }; + + return GNUNET_CRYPTO_eddsa_verify_ (TALER_SIGNATURE_WALLET_RESERVE_CLOSE, + &purpose, + &reserve_sig->eddsa_signature, + &reserve_pub->eddsa_pub); +} + + /* end of wallet_signatures.c */