summaryrefslogtreecommitdiff
path: root/src/util/wallet_signatures.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/wallet_signatures.c')
-rw-r--r--src/util/wallet_signatures.c769
1 files changed, 657 insertions, 112 deletions
diff --git a/src/util/wallet_signatures.c b/src/util/wallet_signatures.c
index 27a28256c..0b6ab5432 100644
--- a/src/util/wallet_signatures.c
+++ b/src/util/wallet_signatures.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2021, 2022 Taler Systems SA
+ Copyright (C) 2021-2023 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
@@ -17,12 +17,16 @@
* @file wallet_signatures.c
* @brief Utility functions for Taler wallet signatures
* @author Christian Grothoff
+ * @author Özgür Kesim
*/
#include "platform.h"
#include "taler_util.h"
#include "taler_signatures.h"
+#include <gnunet/gnunet_common.h>
+GNUNET_NETWORK_STRUCT_BEGIN
+
/**
* @brief Format used to generate the signature on a request to deposit
* a coin into the account of a merchant.
@@ -47,9 +51,9 @@ struct TALER_DepositRequestPS
struct TALER_AgeCommitmentHash h_age_commitment GNUNET_PACKED;
/**
- * Hash over extension attributes shared with the exchange.
+ * Hash over optional policy extension attributes shared with the exchange.
*/
- struct TALER_ExtensionContractHashP h_extensions GNUNET_PACKED;
+ struct TALER_ExtensionPolicyHashP h_policy GNUNET_PACKED;
/**
* Hash over the wiring information of the merchant.
@@ -107,8 +111,15 @@ struct TALER_DepositRequestPS
*/
struct TALER_MerchantPublicKeyP merchant;
+ /**
+ * Hash over a JSON containing data provided by the
+ * wallet to complete the contract upon payment.
+ */
+ struct GNUNET_HashCode wallet_data_hash;
+
};
+GNUNET_NETWORK_STRUCT_END
void
TALER_wallet_deposit_sign (
@@ -116,8 +127,9 @@ TALER_wallet_deposit_sign (
const struct TALER_Amount *deposit_fee,
const struct TALER_MerchantWireHashP *h_wire,
const struct TALER_PrivateContractHashP *h_contract_terms,
+ const struct GNUNET_HashCode *wallet_data_hash,
const struct TALER_AgeCommitmentHash *h_age_commitment,
- const struct TALER_ExtensionContractHashP *h_extensions,
+ const struct TALER_ExtensionPolicyHashP *h_policy,
const struct TALER_DenominationHashP *h_denom_pub,
const struct GNUNET_TIME_Timestamp wallet_timestamp,
const struct TALER_MerchantPublicKeyP *merchant_pub,
@@ -136,12 +148,12 @@ TALER_wallet_deposit_sign (
.merchant = *merchant_pub
};
+ if (NULL != wallet_data_hash)
+ dr.wallet_data_hash = *wallet_data_hash;
if (NULL != h_age_commitment)
dr.h_age_commitment = *h_age_commitment;
-
- if (NULL != h_extensions)
- dr.h_extensions = *h_extensions;
-
+ if (NULL != h_policy)
+ dr.h_policy = *h_policy;
TALER_amount_hton (&dr.amount_with_fee,
amount);
TALER_amount_hton (&dr.deposit_fee,
@@ -158,8 +170,9 @@ TALER_wallet_deposit_verify (
const struct TALER_Amount *deposit_fee,
const struct TALER_MerchantWireHashP *h_wire,
const struct TALER_PrivateContractHashP *h_contract_terms,
+ const struct GNUNET_HashCode *wallet_data_hash,
const struct TALER_AgeCommitmentHash *h_age_commitment,
- const struct TALER_ExtensionContractHashP *h_extensions,
+ const struct TALER_ExtensionPolicyHashP *h_policy,
const struct TALER_DenominationHashP *h_denom_pub,
struct GNUNET_TIME_Timestamp wallet_timestamp,
const struct TALER_MerchantPublicKeyP *merchant_pub,
@@ -176,21 +189,18 @@ TALER_wallet_deposit_verify (
.wallet_timestamp = GNUNET_TIME_timestamp_hton (wallet_timestamp),
.refund_deadline = GNUNET_TIME_timestamp_hton (refund_deadline),
.merchant = *merchant_pub,
- .h_age_commitment = {{{0}}},
- .h_extensions = {{{0}}}
};
+ if (NULL != wallet_data_hash)
+ dr.wallet_data_hash = *wallet_data_hash;
if (NULL != h_age_commitment)
dr.h_age_commitment = *h_age_commitment;
-
- if (NULL != h_extensions)
- dr.h_extensions = *h_extensions;
-
+ if (NULL != h_policy)
+ dr.h_policy = *h_policy;
TALER_amount_hton (&dr.amount_with_fee,
amount);
TALER_amount_hton (&dr.deposit_fee,
deposit_fee);
-
if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_DEPOSIT,
&dr,
@@ -204,6 +214,8 @@ TALER_wallet_deposit_verify (
}
+GNUNET_NETWORK_STRUCT_BEGIN
+
/**
* @brief Format used for to allow the wallet to authenticate
* link data provided by the exchange.
@@ -238,6 +250,7 @@ struct TALER_LinkDataPS
struct TALER_BlindedCoinHashP coin_envelope_hash;
};
+GNUNET_NETWORK_STRUCT_END
void
TALER_wallet_link_sign (const struct TALER_DenominationHashP *h_denom_pub,
@@ -284,6 +297,8 @@ TALER_wallet_link_verify (
}
+GNUNET_NETWORK_STRUCT_BEGIN
+
/**
* 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
@@ -305,15 +320,17 @@ struct TALER_RecoupRequestPS
/**
* Blinding factor that was used to withdraw the coin.
*/
- union TALER_DenominationBlindingKeyP coin_blind;
+ union GNUNET_CRYPTO_BlindingSecretP coin_blind;
};
+GNUNET_NETWORK_STRUCT_END
+
enum GNUNET_GenericReturnValue
TALER_wallet_recoup_verify (
const struct TALER_DenominationHashP *h_denom_pub,
- const union TALER_DenominationBlindingKeyP *coin_bks,
+ const union GNUNET_CRYPTO_BlindingSecretP *coin_bks,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_CoinSpendSignatureP *coin_sig)
{
@@ -334,7 +351,7 @@ TALER_wallet_recoup_verify (
void
TALER_wallet_recoup_sign (
const struct TALER_DenominationHashP *h_denom_pub,
- const union TALER_DenominationBlindingKeyP *coin_bks,
+ const union GNUNET_CRYPTO_BlindingSecretP *coin_bks,
const struct TALER_CoinSpendPrivateKeyP *coin_priv,
struct TALER_CoinSpendSignatureP *coin_sig)
{
@@ -354,7 +371,7 @@ TALER_wallet_recoup_sign (
enum GNUNET_GenericReturnValue
TALER_wallet_recoup_refresh_verify (
const struct TALER_DenominationHashP *h_denom_pub,
- const union TALER_DenominationBlindingKeyP *coin_bks,
+ const union GNUNET_CRYPTO_BlindingSecretP *coin_bks,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_CoinSpendSignatureP *coin_sig)
{
@@ -375,7 +392,7 @@ TALER_wallet_recoup_refresh_verify (
void
TALER_wallet_recoup_refresh_sign (
const struct TALER_DenominationHashP *h_denom_pub,
- const union TALER_DenominationBlindingKeyP *coin_bks,
+ const union GNUNET_CRYPTO_BlindingSecretP *coin_bks,
const struct TALER_CoinSpendPrivateKeyP *coin_priv,
struct TALER_CoinSpendSignatureP *coin_sig)
{
@@ -392,6 +409,8 @@ TALER_wallet_recoup_refresh_sign (
}
+GNUNET_NETWORK_STRUCT_BEGIN
+
/**
* @brief Message signed by a coin to indicate that the coin should be
* melted.
@@ -443,6 +462,7 @@ struct TALER_RefreshMeltCoinAffirmationPS
struct TALER_AmountNBO melt_fee;
};
+GNUNET_NETWORK_STRUCT_END
void
TALER_wallet_melt_sign (
@@ -509,6 +529,9 @@ TALER_wallet_melt_verify (
}
+GNUNET_NETWORK_STRUCT_BEGIN
+
+
/**
* @brief Format used for to generate the signature on a request to withdraw
* coins from a reserve.
@@ -543,6 +566,8 @@ struct TALER_WithdrawRequestPS
};
+GNUNET_NETWORK_STRUCT_END
+
void
TALER_wallet_withdraw_sign (
const struct TALER_DenominationHashP *h_denom_pub,
@@ -591,45 +616,181 @@ TALER_wallet_withdraw_verify (
}
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * @brief Format used for to generate the signature on a request to
+ * age-withdraw from a reserve.
+ */
+struct TALER_AgeWithdrawRequestPS
+{
+
+ /**
+ * Purpose must be #TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW.
+ * Used with an EdDSA signature of a `struct TALER_ReservePublicKeyP`.
+ */
+ struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+ /**
+ * The reserve's public key
+ */
+ struct TALER_ReservePublicKeyP reserve_pub;
+
+ /**
+ * 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;
+
+ /**
+ * Running SHA512 hash of the commitment of n*kappa coins
+ */
+ struct TALER_AgeWithdrawCommitmentHashP h_commitment;
+
+ /**
+ * The mask that defines the age groups. MUST be the same for all denominations.
+ */
+ struct TALER_AgeMask mask;
+
+ /**
+ * Maximum age group that the coins are going to be restricted to.
+ */
+ uint8_t max_age_group;
+};
+
+
+GNUNET_NETWORK_STRUCT_END
+
+void
+TALER_wallet_age_withdraw_sign (
+ const struct TALER_AgeWithdrawCommitmentHashP *h_commitment,
+ const struct TALER_Amount *amount_with_fee,
+ const struct TALER_AgeMask *mask,
+ uint8_t max_age,
+ const struct TALER_ReservePrivateKeyP *reserve_priv,
+ struct TALER_ReserveSignatureP *reserve_sig)
+{
+ struct TALER_AgeWithdrawRequestPS req = {
+ .purpose.size = htonl (sizeof (req)),
+ .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_AGE_WITHDRAW),
+ .h_commitment = *h_commitment,
+ .mask = *mask,
+ .max_age_group = TALER_get_age_group (mask, max_age)
+ };
+
+ GNUNET_CRYPTO_eddsa_key_get_public (&reserve_priv->eddsa_priv,
+ &req.reserve_pub.eddsa_pub);
+ TALER_amount_hton (&req.amount_with_fee,
+ amount_with_fee);
+ GNUNET_CRYPTO_eddsa_sign (&reserve_priv->eddsa_priv,
+ &req,
+ &reserve_sig->eddsa_signature);
+}
+
+
+enum GNUNET_GenericReturnValue
+TALER_wallet_age_withdraw_verify (
+ const struct TALER_AgeWithdrawCommitmentHashP *h_commitment,
+ const struct TALER_Amount *amount_with_fee,
+ const struct TALER_AgeMask *mask,
+ uint8_t max_age,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ const struct TALER_ReserveSignatureP *reserve_sig)
+{
+ struct TALER_AgeWithdrawRequestPS awsrd = {
+ .purpose.size = htonl (sizeof (awsrd)),
+ .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_AGE_WITHDRAW),
+ .reserve_pub = *reserve_pub,
+ .h_commitment = *h_commitment,
+ .mask = *mask,
+ .max_age_group = TALER_get_age_group (mask, max_age)
+ };
+
+ TALER_amount_hton (&awsrd.amount_with_fee,
+ amount_with_fee);
+ return GNUNET_CRYPTO_eddsa_verify (
+ TALER_SIGNATURE_WALLET_RESERVE_AGE_WITHDRAW,
+ &awsrd,
+ &reserve_sig->eddsa_signature,
+ &reserve_pub->eddsa_pub);
+}
+
+
+GNUNET_NETWORK_STRUCT_BEGIN
+
+
+/**
+ * @brief Format used for to generate the signature on a request to withdraw
+ * coins from a reserve.
+ */
+struct TALER_AccountSetupRequestSignaturePS
+{
+
+ /**
+ * Purpose must be #TALER_SIGNATURE_WALLET_ACCOUNT_SETUP.
+ * Used with an EdDSA signature of a `struct TALER_ReservePublicKeyP`.
+ */
+ struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+ /**
+ * Balance threshold the wallet is about to cross.
+ */
+ struct TALER_AmountNBO threshold;
+
+};
+
+
+GNUNET_NETWORK_STRUCT_END
+
+
void
TALER_wallet_account_setup_sign (
const struct TALER_ReservePrivateKeyP *reserve_priv,
+ const struct TALER_Amount *balance_threshold,
struct TALER_ReserveSignatureP *reserve_sig)
{
- struct GNUNET_CRYPTO_EccSignaturePurpose purpose = {
- .size = htonl (sizeof (purpose)),
- .purpose = htonl (TALER_SIGNATURE_WALLET_ACCOUNT_SETUP)
+ struct TALER_AccountSetupRequestSignaturePS asap = {
+ .purpose.size = htonl (sizeof (asap)),
+ .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_ACCOUNT_SETUP)
};
- GNUNET_assert (GNUNET_OK ==
- GNUNET_CRYPTO_eddsa_sign_ (&reserve_priv->eddsa_priv,
- &purpose,
- &reserve_sig->eddsa_signature));
+ TALER_amount_hton (&asap.threshold,
+ balance_threshold);
+ GNUNET_CRYPTO_eddsa_sign (&reserve_priv->eddsa_priv,
+ &asap,
+ &reserve_sig->eddsa_signature);
}
enum GNUNET_GenericReturnValue
TALER_wallet_account_setup_verify (
const struct TALER_ReservePublicKeyP *reserve_pub,
+ const struct TALER_Amount *balance_threshold,
const struct TALER_ReserveSignatureP *reserve_sig)
{
- struct GNUNET_CRYPTO_EccSignaturePurpose purpose = {
- .size = htonl (sizeof (purpose)),
- .purpose = htonl (TALER_SIGNATURE_WALLET_ACCOUNT_SETUP)
+ struct TALER_AccountSetupRequestSignaturePS asap = {
+ .purpose.size = htonl (sizeof (asap)),
+ .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_ACCOUNT_SETUP)
};
- return GNUNET_CRYPTO_eddsa_verify_ (
+ TALER_amount_hton (&asap.threshold,
+ balance_threshold);
+ return GNUNET_CRYPTO_eddsa_verify (
TALER_SIGNATURE_WALLET_ACCOUNT_SETUP,
- &purpose,
+ &asap,
&reserve_sig->eddsa_signature,
&reserve_pub->eddsa_pub);
}
+GNUNET_NETWORK_STRUCT_BEGIN
+
+
/**
- * Response by which a wallet requests a full
- * reserve history and indicates it is willing
- * to pay for it.
+ * Response by which a wallet requests a reserve history.
*/
struct TALER_ReserveHistoryRequestPS
{
@@ -640,35 +801,29 @@ struct TALER_ReserveHistoryRequestPS
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?
+ * Which entries to exclude. Only return above this offset.
*/
- struct TALER_AmountNBO history_fee;
+ uint64_t start_off;
};
+GNUNET_NETWORK_STRUCT_END
+
enum GNUNET_GenericReturnValue
TALER_wallet_reserve_history_verify (
- const struct GNUNET_TIME_Timestamp ts,
- const struct TALER_Amount *history_fee,
+ uint64_t start_off,
const struct TALER_ReservePublicKeyP *reserve_pub,
const struct TALER_ReserveSignatureP *reserve_sig)
{
struct TALER_ReserveHistoryRequestPS rhr = {
.purpose.size = htonl (sizeof (rhr)),
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_HISTORY),
- .request_timestamp = GNUNET_TIME_timestamp_hton (ts)
+ .start_off = GNUNET_htonll (start_off)
};
- TALER_amount_hton (&rhr.history_fee,
- history_fee);
return GNUNET_CRYPTO_eddsa_verify (
- TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW,
+ TALER_SIGNATURE_WALLET_RESERVE_HISTORY,
&rhr,
&reserve_sig->eddsa_signature,
&reserve_pub->eddsa_pub);
@@ -677,82 +832,84 @@ TALER_wallet_reserve_history_verify (
void
TALER_wallet_reserve_history_sign (
- const struct GNUNET_TIME_Timestamp ts,
- const struct TALER_Amount *history_fee,
+ uint64_t start_off,
const struct TALER_ReservePrivateKeyP *reserve_priv,
struct TALER_ReserveSignatureP *reserve_sig)
{
struct TALER_ReserveHistoryRequestPS rhr = {
.purpose.size = htonl (sizeof (rhr)),
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_HISTORY),
- .request_timestamp = GNUNET_TIME_timestamp_hton (ts)
+ .start_off = GNUNET_htonll (start_off)
};
- TALER_amount_hton (&rhr.history_fee,
- history_fee);
GNUNET_CRYPTO_eddsa_sign (&reserve_priv->eddsa_priv,
&rhr,
&reserve_sig->eddsa_signature);
}
+GNUNET_NETWORK_STRUCT_BEGIN
+
/**
- * Response by which a wallet requests an account status.
+ * Response by which a wallet requests a coin history.
*/
-struct TALER_ReserveStatusRequestPS
+struct TALER_CoinHistoryRequestPS
{
/**
- * Purpose is #TALER_SIGNATURE_WALLET_RESERVE_STATUS
+ * Purpose is #TALER_SIGNATURE_WALLET_COIN_HISTORY
*/
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
/**
- * When did the wallet make the requst.
+ * Which entries to exclude. Only return above this offset.
*/
- struct GNUNET_TIME_TimestampNBO request_timestamp;
+ uint64_t start_off;
};
+GNUNET_NETWORK_STRUCT_END
enum GNUNET_GenericReturnValue
-TALER_wallet_reserve_status_verify (
- const struct GNUNET_TIME_Timestamp ts,
- const struct TALER_ReservePublicKeyP *reserve_pub,
- const struct TALER_ReserveSignatureP *reserve_sig)
+TALER_wallet_coin_history_verify (
+ uint64_t start_off,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_CoinSpendSignatureP *coin_sig)
{
- struct TALER_ReserveStatusRequestPS rsr = {
+ struct TALER_CoinHistoryRequestPS rsr = {
.purpose.size = htonl (sizeof (rsr)),
- .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_STATUS),
- .request_timestamp = GNUNET_TIME_timestamp_hton (ts)
+ .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_HISTORY),
+ .start_off = GNUNET_htonll (start_off)
};
return GNUNET_CRYPTO_eddsa_verify (
- TALER_SIGNATURE_WALLET_RESERVE_STATUS,
+ TALER_SIGNATURE_WALLET_COIN_HISTORY,
&rsr,
- &reserve_sig->eddsa_signature,
- &reserve_pub->eddsa_pub);
+ &coin_sig->eddsa_signature,
+ &coin_pub->eddsa_pub);
}
void
-TALER_wallet_reserve_status_sign (
- const struct GNUNET_TIME_Timestamp ts,
- const struct TALER_ReservePrivateKeyP *reserve_priv,
- struct TALER_ReserveSignatureP *reserve_sig)
+TALER_wallet_coin_history_sign (
+ uint64_t start_off,
+ const struct TALER_CoinSpendPrivateKeyP *coin_priv,
+ struct TALER_CoinSpendSignatureP *coin_sig)
{
- struct TALER_ReserveStatusRequestPS rsr = {
+ struct TALER_CoinHistoryRequestPS rsr = {
.purpose.size = htonl (sizeof (rsr)),
- .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_STATUS),
- .request_timestamp = GNUNET_TIME_timestamp_hton (ts)
+ .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_HISTORY),
+ .start_off = GNUNET_htonll (start_off)
};
- GNUNET_CRYPTO_eddsa_sign (&reserve_priv->eddsa_priv,
+ GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv,
&rsr,
- &reserve_sig->eddsa_signature);
+ &coin_sig->eddsa_signature);
}
+GNUNET_NETWORK_STRUCT_BEGIN
+
/**
* Message signed to create a purse (without reserve).
*/
@@ -792,10 +949,13 @@ struct TALER_PurseCreatePS
};
+GNUNET_NETWORK_STRUCT_END
+
+
void
TALER_wallet_purse_create_sign (
struct GNUNET_TIME_Timestamp purse_expiration,
- struct TALER_PrivateContractHashP *h_contract_terms,
+ const struct TALER_PrivateContractHashP *h_contract_terms,
const struct TALER_PurseMergePublicKeyP *merge_pub,
uint32_t min_age,
const struct TALER_Amount *amount,
@@ -822,7 +982,7 @@ TALER_wallet_purse_create_sign (
enum GNUNET_GenericReturnValue
TALER_wallet_purse_create_verify (
struct GNUNET_TIME_Timestamp purse_expiration,
- struct TALER_PrivateContractHashP *h_contract_terms,
+ const struct TALER_PrivateContractHashP *h_contract_terms,
const struct TALER_PurseMergePublicKeyP *merge_pub,
uint32_t min_age,
const struct TALER_Amount *amount,
@@ -848,6 +1008,59 @@ TALER_wallet_purse_create_verify (
}
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * Message signed to delete a purse.
+ */
+struct TALER_PurseDeletePS
+{
+
+ /**
+ * Purpose is #TALER_SIGNATURE_WALLET_PURSE_DELETE
+ */
+ struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+};
+
+
+GNUNET_NETWORK_STRUCT_END
+
+
+void
+TALER_wallet_purse_delete_sign (
+ const struct TALER_PurseContractPrivateKeyP *purse_priv,
+ struct TALER_PurseContractSignatureP *purse_sig)
+{
+ struct TALER_PurseDeletePS pm = {
+ .purpose.size = htonl (sizeof (pm)),
+ .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_DELETE)
+ };
+
+ GNUNET_CRYPTO_eddsa_sign (&purse_priv->eddsa_priv,
+ &pm,
+ &purse_sig->eddsa_signature);
+}
+
+
+enum GNUNET_GenericReturnValue
+TALER_wallet_purse_delete_verify (
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ const struct TALER_PurseContractSignatureP *purse_sig)
+{
+ struct TALER_PurseDeletePS pm = {
+ .purpose.size = htonl (sizeof (pm)),
+ .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_DELETE)
+ };
+
+ return GNUNET_CRYPTO_eddsa_verify (
+ TALER_SIGNATURE_WALLET_PURSE_DELETE,
+ &pm,
+ &purse_sig->eddsa_signature,
+ &purse_pub->eddsa_pub);
+}
+
+
void
TALER_wallet_purse_status_sign (
const struct TALER_PurseContractPrivateKeyP *purse_priv,
@@ -882,6 +1095,8 @@ TALER_wallet_purse_status_verify (
}
+GNUNET_NETWORK_STRUCT_BEGIN
+
/**
* Message signed to deposit a coin into a purse.
*/
@@ -899,6 +1114,17 @@ struct TALER_PurseDepositPS
struct TALER_AmountNBO coin_amount;
/**
+ * Hash over the denomination public key used to sign the coin.
+ */
+ struct TALER_DenominationHashP h_denom_pub 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;
+
+ /**
* Purse to deposit funds into.
*/
struct TALER_PurseContractPublicKeyP purse_pub;
@@ -907,15 +1133,18 @@ struct TALER_PurseDepositPS
* Hash of the base URL of the exchange hosting the
* @e purse_pub.
*/
- struct GNUNET_HashCode h_exchange_base_url;
+ struct GNUNET_HashCode h_exchange_base_url GNUNET_PACKED;
};
+GNUNET_NETWORK_STRUCT_END
void
TALER_wallet_purse_deposit_sign (
const char *exchange_base_url,
const struct TALER_PurseContractPublicKeyP *purse_pub,
const struct TALER_Amount *amount,
+ const struct TALER_DenominationHashP *h_denom_pub,
+ const struct TALER_AgeCommitmentHash *h_age_commitment,
const struct TALER_CoinSpendPrivateKeyP *coin_priv,
struct TALER_CoinSpendSignatureP *coin_sig)
{
@@ -923,6 +1152,8 @@ TALER_wallet_purse_deposit_sign (
.purpose.size = htonl (sizeof (pm)),
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_DEPOSIT),
.purse_pub = *purse_pub,
+ .h_denom_pub = *h_denom_pub,
+ .h_age_commitment = *h_age_commitment
};
GNUNET_CRYPTO_hash (exchange_base_url,
@@ -941,6 +1172,8 @@ TALER_wallet_purse_deposit_verify (
const char *exchange_base_url,
const struct TALER_PurseContractPublicKeyP *purse_pub,
const struct TALER_Amount *amount,
+ const struct TALER_DenominationHashP *h_denom_pub,
+ const struct TALER_AgeCommitmentHash *h_age_commitment,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_CoinSpendSignatureP *coin_sig)
{
@@ -948,6 +1181,8 @@ TALER_wallet_purse_deposit_verify (
.purpose.size = htonl (sizeof (pm)),
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_DEPOSIT),
.purse_pub = *purse_pub,
+ .h_denom_pub = *h_denom_pub,
+ .h_age_commitment = *h_age_commitment
};
GNUNET_CRYPTO_hash (exchange_base_url,
@@ -963,6 +1198,8 @@ TALER_wallet_purse_deposit_verify (
}
+GNUNET_NETWORK_STRUCT_BEGIN
+
/**
* Message signed to merge a purse into a reserve.
*/
@@ -992,10 +1229,11 @@ struct TALER_PurseMergePS
};
+GNUNET_NETWORK_STRUCT_END
void
TALER_wallet_purse_merge_sign (
- const char *reserve_url,
+ const char *reserve_uri,
struct GNUNET_TIME_Timestamp merge_timestamp,
const struct TALER_PurseContractPublicKeyP *purse_pub,
const struct TALER_PurseMergePrivateKeyP *merge_priv,
@@ -1008,7 +1246,11 @@ TALER_wallet_purse_merge_sign (
.purse_pub = *purse_pub
};
- TALER_payto_hash (reserve_url,
+ GNUNET_assert (0 ==
+ strncasecmp (reserve_uri,
+ "payto://taler-reserve",
+ strlen ("payto://taler-reserve")));
+ TALER_payto_hash (reserve_uri,
&pm.h_payto);
GNUNET_CRYPTO_eddsa_sign (&merge_priv->eddsa_priv,
&pm,
@@ -1018,7 +1260,7 @@ TALER_wallet_purse_merge_sign (
enum GNUNET_GenericReturnValue
TALER_wallet_purse_merge_verify (
- const char *reserve_url,
+ const char *reserve_uri,
struct GNUNET_TIME_Timestamp merge_timestamp,
const struct TALER_PurseContractPublicKeyP *purse_pub,
const struct TALER_PurseMergePublicKeyP *merge_pub,
@@ -1031,7 +1273,15 @@ TALER_wallet_purse_merge_verify (
.purse_pub = *purse_pub
};
- TALER_payto_hash (reserve_url,
+ if (0 !=
+ strncasecmp (reserve_uri,
+ "payto://taler-reserve",
+ strlen ("payto://taler-reserve")))
+ {
+ GNUNET_break (0);
+ return GNUNET_NO;
+ }
+ TALER_payto_hash (reserve_uri,
&pm.h_payto);
return GNUNET_CRYPTO_eddsa_verify (
TALER_SIGNATURE_WALLET_PURSE_MERGE,
@@ -1041,6 +1291,8 @@ TALER_wallet_purse_merge_verify (
}
+GNUNET_NETWORK_STRUCT_BEGIN
+
/**
* Message signed by account to merge a purse into a reserve.
*/
@@ -1096,6 +1348,8 @@ struct TALER_AccountMergePS
uint32_t flags GNUNET_PACKED;
};
+GNUNET_NETWORK_STRUCT_END
+
void
TALER_wallet_account_merge_sign (
@@ -1167,40 +1421,323 @@ TALER_wallet_account_merge_verify (
}
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * Message signed by reserve key.
+ */
+struct TALER_ReserveOpenPS
+{
+
+ /**
+ * Purpose is #TALER_SIGNATURE_WALLET_RESERVE_OPEN
+ */
+ struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+ /**
+ * Amount to be paid from the reserve balance to open
+ * the reserve.
+ */
+ struct TALER_AmountNBO reserve_payment;
+
+ /**
+ * When was the request created.
+ */
+ struct GNUNET_TIME_TimestampNBO request_timestamp;
+
+ /**
+ * For how long should the reserve be kept open.
+ * (Determines amount to be paid.)
+ */
+ struct GNUNET_TIME_TimestampNBO reserve_expiration;
+
+ /**
+ * How many open purses should be included with the
+ * open reserve?
+ * (Determines amount to be paid.)
+ */
+ uint32_t purse_limit GNUNET_PACKED;
+
+};
+
+GNUNET_NETWORK_STRUCT_END
+
+
void
-TALER_wallet_account_close_sign (
+TALER_wallet_reserve_open_sign (
+ const struct TALER_Amount *reserve_payment,
+ struct GNUNET_TIME_Timestamp request_timestamp,
+ struct GNUNET_TIME_Timestamp reserve_expiration,
+ uint32_t purse_limit,
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)
+ struct TALER_ReserveOpenPS rop = {
+ .purpose.size = htonl (sizeof (rop)),
+ .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_OPEN),
+ .request_timestamp = GNUNET_TIME_timestamp_hton (request_timestamp),
+ .reserve_expiration = GNUNET_TIME_timestamp_hton (reserve_expiration),
+ .purse_limit = htonl (purse_limit)
};
+ TALER_amount_hton (&rop.reserve_payment,
+ reserve_payment);
GNUNET_assert (GNUNET_OK ==
GNUNET_CRYPTO_eddsa_sign_ (&reserve_priv->eddsa_priv,
- &purpose,
+ &rop.purpose,
&reserve_sig->eddsa_signature));
}
enum GNUNET_GenericReturnValue
-TALER_wallet_account_close_verify (
+TALER_wallet_reserve_open_verify (
+ const struct TALER_Amount *reserve_payment,
+ struct GNUNET_TIME_Timestamp request_timestamp,
+ struct GNUNET_TIME_Timestamp reserve_expiration,
+ uint32_t purse_limit,
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)
+ struct TALER_ReserveOpenPS rop = {
+ .purpose.size = htonl (sizeof (rop)),
+ .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_OPEN),
+ .request_timestamp = GNUNET_TIME_timestamp_hton (request_timestamp),
+ .reserve_expiration = GNUNET_TIME_timestamp_hton (reserve_expiration),
+ .purse_limit = htonl (purse_limit)
};
+ TALER_amount_hton (&rop.reserve_payment,
+ reserve_payment);
+ return GNUNET_CRYPTO_eddsa_verify_ (TALER_SIGNATURE_WALLET_RESERVE_OPEN,
+ &rop.purpose,
+ &reserve_sig->eddsa_signature,
+ &reserve_pub->eddsa_pub);
+}
+
+
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * Message signed by
+ */
+struct TALER_ReserveOpenDepositPS
+{
+
+ /**
+ * Purpose is #TALER_SIGNATURE_WALLET_RESERVE_OPEN_DEPOSIT
+ */
+ struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+ /**
+ * Which reserve's opening signature should be paid for?
+ */
+ struct TALER_ReserveSignatureP reserve_sig;
+
+ /**
+ * Specifies how much of the coin's value should be spent on opening this
+ * reserve.
+ */
+ struct TALER_AmountNBO coin_contribution;
+};
+
+GNUNET_NETWORK_STRUCT_END
+
+
+// FIXME-#7267: add h_age_commitment, h_denom_pub to have proof!
+void
+TALER_wallet_reserve_open_deposit_sign (
+ const struct TALER_Amount *coin_contribution,
+ const struct TALER_ReserveSignatureP *reserve_sig,
+ const struct TALER_CoinSpendPrivateKeyP *coin_priv,
+ struct TALER_CoinSpendSignatureP *coin_sig)
+{
+ struct TALER_ReserveOpenDepositPS rod = {
+ .purpose.size = htonl (sizeof (rod)),
+ .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_OPEN_DEPOSIT),
+ .reserve_sig = *reserve_sig
+ };
+
+ TALER_amount_hton (&rod.coin_contribution,
+ coin_contribution);
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_CRYPTO_eddsa_sign_ (&coin_priv->eddsa_priv,
+ &rod.purpose,
+ &coin_sig->eddsa_signature));
+}
+
+
+enum GNUNET_GenericReturnValue
+TALER_wallet_reserve_open_deposit_verify (
+ const struct TALER_Amount *coin_contribution,
+ const struct TALER_ReserveSignatureP *reserve_sig,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_CoinSpendSignatureP *coin_sig)
+{
+ struct TALER_ReserveOpenDepositPS rod = {
+ .purpose.size = htonl (sizeof (rod)),
+ .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_OPEN_DEPOSIT),
+ .reserve_sig = *reserve_sig
+ };
+
+ TALER_amount_hton (&rod.coin_contribution,
+ coin_contribution);
+ return GNUNET_CRYPTO_eddsa_verify_ (
+ TALER_SIGNATURE_WALLET_RESERVE_OPEN_DEPOSIT,
+ &rod.purpose,
+ &coin_sig->eddsa_signature,
+ &coin_pub->eddsa_pub);
+}
+
+
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * Message signed by reserve key.
+ */
+struct TALER_ReserveClosePS
+{
+
+ /**
+ * Purpose is #TALER_SIGNATURE_WALLET_RESERVE_CLOSE
+ */
+ struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+ /**
+ * When was the request created.
+ */
+ struct GNUNET_TIME_TimestampNBO request_timestamp;
+
+ /**
+ * Hash of the payto://-URI of the target account
+ * for the closure, or all zeros for the reserve
+ * origin account.
+ */
+ struct TALER_PaytoHashP target_account_h_payto;
+
+};
+
+GNUNET_NETWORK_STRUCT_END
+
+
+void
+TALER_wallet_reserve_close_sign (
+ struct GNUNET_TIME_Timestamp request_timestamp,
+ const struct TALER_PaytoHashP *h_payto,
+ const struct TALER_ReservePrivateKeyP *reserve_priv,
+ struct TALER_ReserveSignatureP *reserve_sig)
+{
+ struct TALER_ReserveClosePS rcp = {
+ .purpose.size = htonl (sizeof (rcp)),
+ .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_CLOSE),
+ .request_timestamp = GNUNET_TIME_timestamp_hton (request_timestamp)
+ };
+
+ if (NULL != h_payto)
+ rcp.target_account_h_payto = *h_payto;
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_CRYPTO_eddsa_sign_ (&reserve_priv->eddsa_priv,
+ &rcp.purpose,
+ &reserve_sig->eddsa_signature));
+}
+
+
+enum GNUNET_GenericReturnValue
+TALER_wallet_reserve_close_verify (
+ struct GNUNET_TIME_Timestamp request_timestamp,
+ const struct TALER_PaytoHashP *h_payto,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ const struct TALER_ReserveSignatureP *reserve_sig)
+{
+ struct TALER_ReserveClosePS rcp = {
+ .purpose.size = htonl (sizeof (rcp)),
+ .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_CLOSE),
+ .request_timestamp = GNUNET_TIME_timestamp_hton (request_timestamp)
+ };
+
+ if (NULL != h_payto)
+ rcp.target_account_h_payto = *h_payto;
return GNUNET_CRYPTO_eddsa_verify_ (TALER_SIGNATURE_WALLET_RESERVE_CLOSE,
- &purpose,
+ &rcp.purpose,
&reserve_sig->eddsa_signature,
&reserve_pub->eddsa_pub);
}
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * Message signed by reserve private key.
+ */
+struct TALER_ReserveAttestRequestPS
+{
+
+ /**
+ * Purpose is #TALER_SIGNATURE_WALLET_ATTEST_REQUEST
+ */
+ struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+ /**
+ * When was the request created.
+ */
+ struct GNUNET_TIME_TimestampNBO request_timestamp;
+
+ /**
+ * Hash over the JSON array of requested attributes.
+ */
+ struct GNUNET_HashCode h_details;
+
+};
+
+GNUNET_NETWORK_STRUCT_END
+
+
+void
+TALER_wallet_reserve_attest_request_sign (
+ struct GNUNET_TIME_Timestamp request_timestamp,
+ const json_t *details,
+ const struct TALER_ReservePrivateKeyP *reserve_priv,
+ struct TALER_ReserveSignatureP *reserve_sig)
+{
+ struct TALER_ReserveAttestRequestPS rcp = {
+ .purpose.size = htonl (sizeof (rcp)),
+ .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_ATTEST_DETAILS),
+ .request_timestamp = GNUNET_TIME_timestamp_hton (request_timestamp)
+ };
+
+ TALER_json_hash (details,
+ &rcp.h_details);
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_CRYPTO_eddsa_sign_ (&reserve_priv->eddsa_priv,
+ &rcp.purpose,
+ &reserve_sig->eddsa_signature));
+}
+
+
+enum GNUNET_GenericReturnValue
+TALER_wallet_reserve_attest_request_verify (
+ struct GNUNET_TIME_Timestamp request_timestamp,
+ const json_t *details,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ const struct TALER_ReserveSignatureP *reserve_sig)
+{
+ struct TALER_ReserveAttestRequestPS rcp = {
+ .purpose.size = htonl (sizeof (rcp)),
+ .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_ATTEST_DETAILS),
+ .request_timestamp = GNUNET_TIME_timestamp_hton (request_timestamp)
+ };
+
+ TALER_json_hash (details,
+ &rcp.h_details);
+ return GNUNET_CRYPTO_eddsa_verify_ (
+ TALER_SIGNATURE_WALLET_RESERVE_ATTEST_DETAILS,
+ &rcp.purpose,
+ &reserve_sig->eddsa_signature,
+ &reserve_pub->eddsa_pub);
+}
+
+
+GNUNET_NETWORK_STRUCT_BEGIN
+
/**
* Message signed by purse to associate an encrypted contract.
*/
@@ -1223,6 +1760,7 @@ struct TALER_PurseContractPS
struct TALER_ContractDiffiePublicP contract_pub;
};
+GNUNET_NETWORK_STRUCT_END
void
TALER_wallet_econtract_upload_sign (
@@ -1248,20 +1786,9 @@ TALER_wallet_econtract_upload_sign (
}
-/**
- * Verify a signature over encrypted contract.
- *
- * @param econtract encrypted contract
- * @param econtract_size number of bytes in @a econtract
- * @param contract_pub public key for the DH-encryption
- * @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_econtract_upload_verify (
- const void *econtract,
- size_t econtract_size,
+TALER_wallet_econtract_upload_verify2 (
+ const struct GNUNET_HashCode *h_econtract,
const struct TALER_ContractDiffiePublicP *contract_pub,
const struct TALER_PurseContractPublicKeyP *purse_pub,
const struct TALER_PurseContractSignatureP *purse_sig)
@@ -1269,12 +1796,10 @@ TALER_wallet_econtract_upload_verify (
struct TALER_PurseContractPS pc = {
.purpose.size = htonl (sizeof (pc)),
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_ECONTRACT),
- .contract_pub = *contract_pub
+ .contract_pub = *contract_pub,
+ .h_econtract = *h_econtract
};
- GNUNET_CRYPTO_hash (econtract,
- econtract_size,
- &pc.h_econtract);
return GNUNET_CRYPTO_eddsa_verify_ (TALER_SIGNATURE_WALLET_PURSE_ECONTRACT,
&pc.purpose,
&purse_sig->eddsa_signature,
@@ -1282,4 +1807,24 @@ TALER_wallet_econtract_upload_verify (
}
+enum GNUNET_GenericReturnValue
+TALER_wallet_econtract_upload_verify (
+ const void *econtract,
+ size_t econtract_size,
+ const struct TALER_ContractDiffiePublicP *contract_pub,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ const struct TALER_PurseContractSignatureP *purse_sig)
+{
+ struct GNUNET_HashCode h_econtract;
+
+ GNUNET_CRYPTO_hash (econtract,
+ econtract_size,
+ &h_econtract);
+ return TALER_wallet_econtract_upload_verify2 (&h_econtract,
+ contract_pub,
+ purse_pub,
+ purse_sig);
+}
+
+
/* end of wallet_signatures.c */