summaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2022-09-18 17:36:35 +0200
committerChristian Grothoff <christian@grothoff.org>2022-09-18 17:36:35 +0200
commit18a2fae3b594f7ef54104b708d00641f6ed5de1e (patch)
treee70dff8fb8bab32838c5b6d1da04eb31abf6e46e /src/util
parentb4b857abeaa0447b8dd4626f303ce7cdb728f0b7 (diff)
downloadexchange-18a2fae3b594f7ef54104b708d00641f6ed5de1e.tar.gz
exchange-18a2fae3b594f7ef54104b708d00641f6ed5de1e.tar.bz2
exchange-18a2fae3b594f7ef54104b708d00641f6ed5de1e.zip
add new signature functions for DD31
Diffstat (limited to 'src/util')
-rw-r--r--src/util/exchange_signatures.c99
-rw-r--r--src/util/util.c25
-rw-r--r--src/util/wallet_signatures.c357
3 files changed, 467 insertions, 14 deletions
diff --git a/src/util/exchange_signatures.c b/src/util/exchange_signatures.c
index 52919d2e9..d42f70d66 100644
--- a/src/util/exchange_signatures.c
+++ b/src/util/exchange_signatures.c
@@ -1591,4 +1591,103 @@ TALER_exchange_online_purse_status_verify (
}
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * Message signed by the exchange to affirm that the
+ * owner of a reserve has certain attributes.
+ */
+struct TALER_ExchangeAttestPS
+{
+
+ /**
+ * Purpose is #TALER_SIGNATURE_EXCHANGE_RESERVE_ATTEST_DETAILS
+ */
+ struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+ /**
+ * Time when the attestation was made.
+ */
+ struct GNUNET_TIME_TimestampNBO attest_timestamp;
+
+ /**
+ * Time when the attestation expires.
+ */
+ struct GNUNET_TIME_TimestampNBO expiration_time;
+
+ /**
+ * Public key of the reserve for which the attributes
+ * are attested.
+ */
+ struct TALER_ReservePublicKeyP reserve_pub;
+
+ /**
+ * Hash over the attributes.
+ */
+ struct GNUNET_HashCode h_attributes;
+
+};
+
+GNUNET_NETWORK_STRUCT_END
+
+
+enum TALER_ErrorCode
+TALER_exchange_online_reserve_attest_details_sign (
+ TALER_ExchangeSignCallback scb,
+ struct GNUNET_TIME_Timestamp attest_timestamp,
+ struct GNUNET_TIME_Timestamp expiration_time,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ const json_t *attributes,
+ struct TALER_ExchangePublicKeyP *pub,
+ struct TALER_ExchangeSignatureP *sig)
+{
+ struct TALER_ExchangeAttestPS rap = {
+ .purpose.size = htonl (sizeof (rap)),
+ .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_ATTEST_DETAILS),
+ .attest_timestamp = GNUNET_TIME_timestamp_hton (attest_timestamp),
+ .expiration_time = GNUNET_TIME_timestamp_hton (expiration_time),
+ .reserve_pub = *reserve_pub
+ };
+
+ TALER_json_hash (attributes,
+ &rap.h_attributes);
+ return scb (&rap.purpose,
+ pub,
+ sig);
+}
+
+
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_reserve_attest_details_verify (
+ struct GNUNET_TIME_Timestamp attest_timestamp,
+ struct GNUNET_TIME_Timestamp expiration_time,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ const json_t *attributes,
+ struct TALER_ExchangePublicKeyP *pub,
+ struct TALER_ExchangeSignatureP *sig)
+{
+ struct TALER_ExchangeAttestPS rap = {
+ .purpose.size = htonl (sizeof (rap)),
+ .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_ATTEST_DETAILS),
+ .attest_timestamp = GNUNET_TIME_timestamp_hton (attest_timestamp),
+ .expiration_time = GNUNET_TIME_timestamp_hton (expiration_time),
+ .reserve_pub = *reserve_pub
+ };
+
+ TALER_json_hash (attributes,
+ &rap.h_attributes);
+ if (GNUNET_OK !=
+ GNUNET_CRYPTO_eddsa_verify (
+ TALER_SIGNATURE_EXCHANGE_RESERVE_ATTEST_DETAILS,
+ &rap,
+ &sig->eddsa_signature,
+ &pub->eddsa_pub))
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ return GNUNET_OK;
+}
+
+
/* end of exchange_signatures.c */
diff --git a/src/util/util.c b/src/util/util.c
index 2d10fd69d..f715456d8 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -217,6 +217,31 @@ TALER_denom_fee_check_currency (
}
+/**
+ * Hash normalized @a j JSON object or array and
+ * store the result in @a hc.
+ *
+ * @param j JSON to hash
+ * @param[out] hc where to write the hash
+ */
+void
+TALER_json_hash (const json_t *j,
+ struct GNUNET_HashCode *hc)
+{
+ char *cstr;
+ size_t clen;
+
+ cstr = json_dumps (j,
+ JSON_COMPACT | JSON_SORT_KEYS);
+ GNUNET_assert (NULL != cstr);
+ clen = strlen (cstr);
+ GNUNET_CRYPTO_hash (cstr,
+ clen,
+ hc);
+ free (cstr);
+}
+
+
#ifdef __APPLE__
char *
strchrnul (const char *s,
diff --git a/src/util/wallet_signatures.c b/src/util/wallet_signatures.c
index 64c9ebcba..4e4932a2b 100644
--- a/src/util/wallet_signatures.c
+++ b/src/util/wallet_signatures.c
@@ -23,6 +23,8 @@
#include "taler_signatures.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.
@@ -109,6 +111,7 @@ struct TALER_DepositRequestPS
};
+GNUNET_NETWORK_STRUCT_END
void
TALER_wallet_deposit_sign (
@@ -199,6 +202,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.
@@ -233,6 +238,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,
@@ -279,6 +285,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
@@ -304,6 +312,8 @@ struct TALER_RecoupRequestPS
};
+GNUNET_NETWORK_STRUCT_END
+
enum GNUNET_GenericReturnValue
TALER_wallet_recoup_verify (
@@ -387,6 +397,8 @@ TALER_wallet_recoup_refresh_sign (
}
+GNUNET_NETWORK_STRUCT_BEGIN
+
/**
* @brief Message signed by a coin to indicate that the coin should be
* melted.
@@ -438,6 +450,7 @@ struct TALER_RefreshMeltCoinAffirmationPS
struct TALER_AmountNBO melt_fee;
};
+GNUNET_NETWORK_STRUCT_END
void
TALER_wallet_melt_sign (
@@ -504,6 +517,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.
@@ -538,6 +554,8 @@ struct TALER_WithdrawRequestPS
};
+GNUNET_NETWORK_STRUCT_END
+
void
TALER_wallet_withdraw_sign (
const struct TALER_DenominationHashP *h_denom_pub,
@@ -621,6 +639,8 @@ TALER_wallet_account_setup_verify (
}
+GNUNET_NETWORK_STRUCT_BEGIN
+
/**
* Response by which a wallet requests a full
* reserve history and indicates it is willing
@@ -647,6 +667,9 @@ struct TALER_ReserveHistoryRequestPS
};
+GNUNET_NETWORK_STRUCT_END
+
+
enum GNUNET_GenericReturnValue
TALER_wallet_reserve_history_verify (
const struct GNUNET_TIME_Timestamp ts,
@@ -691,6 +714,8 @@ TALER_wallet_reserve_history_sign (
}
+GNUNET_NETWORK_STRUCT_BEGIN
+
/**
* Response by which a wallet requests an account status.
*/
@@ -709,6 +734,7 @@ struct TALER_ReserveStatusRequestPS
};
+GNUNET_NETWORK_STRUCT_END
enum GNUNET_GenericReturnValue
TALER_wallet_reserve_status_verify (
@@ -748,6 +774,8 @@ TALER_wallet_reserve_status_sign (
}
+GNUNET_NETWORK_STRUCT_BEGIN
+
/**
* Message signed to create a purse (without reserve).
*/
@@ -787,6 +815,9 @@ struct TALER_PurseCreatePS
};
+GNUNET_NETWORK_STRUCT_END
+
+
void
TALER_wallet_purse_create_sign (
struct GNUNET_TIME_Timestamp purse_expiration,
@@ -877,6 +908,8 @@ TALER_wallet_purse_status_verify (
}
+GNUNET_NETWORK_STRUCT_BEGIN
+
/**
* Message signed to deposit a coin into a purse.
*/
@@ -916,6 +949,7 @@ struct TALER_PurseDepositPS
struct GNUNET_HashCode h_exchange_base_url GNUNET_PACKED;
};
+GNUNET_NETWORK_STRUCT_END
void
TALER_wallet_purse_deposit_sign (
@@ -977,6 +1011,8 @@ TALER_wallet_purse_deposit_verify (
}
+GNUNET_NETWORK_STRUCT_BEGIN
+
/**
* Message signed to merge a purse into a reserve.
*/
@@ -1006,6 +1042,7 @@ struct TALER_PurseMergePS
};
+GNUNET_NETWORK_STRUCT_END
void
TALER_wallet_purse_merge_sign (
@@ -1067,6 +1104,8 @@ TALER_wallet_purse_merge_verify (
}
+GNUNET_NETWORK_STRUCT_BEGIN
+
/**
* Message signed by account to merge a purse into a reserve.
*/
@@ -1122,6 +1161,8 @@ struct TALER_AccountMergePS
uint32_t flags GNUNET_PACKED;
};
+GNUNET_NETWORK_STRUCT_END
+
void
TALER_wallet_account_merge_sign (
@@ -1193,44 +1234,331 @@ TALER_wallet_account_merge_verify (
}
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * Message signed by
+ */
+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 (
- // FIXME: add max amount (optional)
- // timestamp, target account (optional)
+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 (
- // FIXME: add max amount (optional),
- // timestamp, target account (optional)
+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;
+
+ /**
+ * When was the request created.
+ */
+ struct GNUNET_TIME_TimestampNBO request_timestamp;
+
+ /**
+ * Which reserve's opening should be paid for?
+ */
+ struct TALER_ReservePublicKeyP reserve_pub;
+
+ /**
+ * Specifies how much of the coin's value should be spent on opening this
+ * reserve.
+ */
+ struct TALER_AmountNBO coin_contribution;
+};
+
+GNUNET_NETWORK_STRUCT_END
+
+
+void
+TALER_wallet_reserve_open_deposit_sign (
+ const struct TALER_Amount *coin_contribution,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ struct GNUNET_TIME_Timestamp request_timestamp,
+ 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),
+ .request_timestamp = GNUNET_TIME_timestamp_hton (request_timestamp),
+ .reserve_pub = *reserve_pub
};
+ 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_ReservePublicKeyP *reserve_pub,
+ struct GNUNET_TIME_Timestamp request_timestamp,
+ 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),
+ .request_timestamp = GNUNET_TIME_timestamp_hton (request_timestamp),
+ .reserve_pub = *reserve_pub
+ };
+
+ 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
+ */
+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
+ * origina ccount.
+ */
+ 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
+ */
+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.
*/
@@ -1253,6 +1581,7 @@ struct TALER_PurseContractPS
struct TALER_ContractDiffiePublicP contract_pub;
};
+GNUNET_NETWORK_STRUCT_END
void
TALER_wallet_econtract_upload_sign (