diff options
author | Christian Grothoff <grothoff@gnunet.org> | 2022-03-22 02:33:51 +0100 |
---|---|---|
committer | Christian Grothoff <grothoff@gnunet.org> | 2022-03-22 02:33:51 +0100 |
commit | e200e860321abdff235863bd83e663ae57cf037a (patch) | |
tree | dd0c3429a3e0438fad970bfa2eee303b5c3c9ec5 /src/util | |
parent | bdc797a5830983e22b42bf8d97c25d80ad9f6346 (diff) | |
download | exchange-e200e860321abdff235863bd83e663ae57cf037a.tar.gz exchange-e200e860321abdff235863bd83e663ae57cf037a.tar.bz2 exchange-e200e860321abdff235863bd83e663ae57cf037a.zip |
implement helper functions for p2p signatures, clean up existing signature logic
Diffstat (limited to 'src/util')
-rw-r--r-- | src/util/age_restriction.c | 22 | ||||
-rw-r--r-- | src/util/crypto_wire.c | 82 | ||||
-rw-r--r-- | src/util/merchant_signatures.c | 100 | ||||
-rw-r--r-- | src/util/offline_signatures.c | 321 | ||||
-rw-r--r-- | src/util/wallet_signatures.c | 703 |
5 files changed, 1146 insertions, 82 deletions
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, @@ -374,6 +608,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, const struct TALER_Amount *history_fee, @@ -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 */ |