summaryrefslogtreecommitdiff
path: root/src/util/offline_signatures.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/offline_signatures.c')
-rw-r--r--src/util/offline_signatures.c956
1 files changed, 907 insertions, 49 deletions
diff --git a/src/util/offline_signatures.c b/src/util/offline_signatures.c
index 1240a8bc5..fbff850df 100644
--- a/src/util/offline_signatures.c
+++ b/src/util/offline_signatures.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2020, 2021 Taler Systems SA
+ Copyright (C) 2020-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
@@ -23,6 +23,132 @@
#include "taler_signatures.h"
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * @brief Signature made by the exchange offline key over the information of
+ * an AML officer status change.
+ */
+struct TALER_MasterAmlOfficerStatusPS
+{
+
+ /**
+ * Purpose is #TALER_SIGNATURE_MASTER_AML_KEY. Signed
+ * by a `struct TALER_MasterPublicKeyP` using EdDSA.
+ */
+ struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+ /**
+ * Time of the change.
+ */
+ struct GNUNET_TIME_TimestampNBO change_date;
+
+ /**
+ * Public key of the AML officer.
+ */
+ struct TALER_AmlOfficerPublicKeyP officer_pub;
+
+ /**
+ * Hash over the AML officer's name.
+ */
+ struct GNUNET_HashCode h_officer_name GNUNET_PACKED;
+
+ /**
+ * Bitmask: 1 if enabled; 2 for read-only access. in NBO.
+ */
+ uint32_t is_active GNUNET_PACKED;
+};
+GNUNET_NETWORK_STRUCT_END
+
+
+void
+TALER_exchange_offline_aml_officer_status_sign (
+ const struct TALER_AmlOfficerPublicKeyP *officer_pub,
+ const char *officer_name,
+ struct GNUNET_TIME_Timestamp change_date,
+ bool is_active,
+ bool read_only,
+ const struct TALER_MasterPrivateKeyP *master_priv,
+ struct TALER_MasterSignatureP *master_sig)
+{
+ struct TALER_MasterAmlOfficerStatusPS as = {
+ .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_AML_KEY),
+ .purpose.size = htonl (sizeof (as)),
+ .change_date = GNUNET_TIME_timestamp_hton (change_date),
+ .officer_pub = *officer_pub,
+ .is_active = htonl ((is_active ? 1 : 0) + (read_only ? 2 : 0))
+ };
+
+ GNUNET_CRYPTO_hash (officer_name,
+ strlen (officer_name) + 1,
+ &as.h_officer_name);
+ GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
+ &as,
+ &master_sig->eddsa_signature);
+}
+
+
+enum GNUNET_GenericReturnValue
+TALER_exchange_offline_aml_officer_status_verify (
+ const struct TALER_AmlOfficerPublicKeyP *officer_pub,
+ const char *officer_name,
+ struct GNUNET_TIME_Timestamp change_date,
+ bool is_active,
+ bool read_only,
+ const struct TALER_MasterPublicKeyP *master_pub,
+ const struct TALER_MasterSignatureP *master_sig)
+{
+ struct TALER_MasterAmlOfficerStatusPS as = {
+ .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_AML_KEY),
+ .purpose.size = htonl (sizeof (as)),
+ .change_date = GNUNET_TIME_timestamp_hton (change_date),
+ .officer_pub = *officer_pub,
+ .is_active = htonl ((is_active ? 1 : 0) + (read_only ? 2 : 0))
+ };
+
+ GNUNET_CRYPTO_hash (officer_name,
+ strlen (officer_name) + 1,
+ &as.h_officer_name);
+ return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_AML_KEY,
+ &as,
+ &master_sig->eddsa_signature,
+ &master_pub->eddsa_pub);
+}
+
+
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * @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;
+};
+GNUNET_NETWORK_STRUCT_END
+
+
void
TALER_exchange_offline_auditor_add_sign (
const struct TALER_AuditorPublicKeyP *auditor_pub,
@@ -73,6 +199,35 @@ TALER_exchange_offline_auditor_add_verify (
}
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * @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;
+
+};
+GNUNET_NETWORK_STRUCT_END
+
+
void
TALER_exchange_offline_auditor_del_sign (
const struct TALER_AuditorPublicKeyP *auditor_pub,
@@ -115,9 +270,31 @@ TALER_exchange_offline_auditor_del_verify (
}
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * @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;
+
+};
+
+GNUNET_NETWORK_STRUCT_END
+
+
void
TALER_exchange_offline_denomination_revoke_sign (
- const struct TALER_DenominationHash *h_denom_pub,
+ const struct TALER_DenominationHashP *h_denom_pub,
const struct TALER_MasterPrivateKeyP *master_priv,
struct TALER_MasterSignatureP *master_sig)
{
@@ -135,7 +312,7 @@ TALER_exchange_offline_denomination_revoke_sign (
enum GNUNET_GenericReturnValue
TALER_exchange_offline_denomination_revoke_verify (
- const struct TALER_DenominationHash *h_denom_pub,
+ const struct TALER_DenominationHashP *h_denom_pub,
const struct TALER_MasterPublicKeyP *master_pub,
const struct TALER_MasterSignatureP *master_sig)
{
@@ -154,6 +331,28 @@ TALER_exchange_offline_denomination_revoke_verify (
}
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * @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;
+
+};
+
+GNUNET_NETWORK_STRUCT_END
+
+
void
TALER_exchange_offline_signkey_revoke_sign (
const struct TALER_ExchangePublicKeyP *exchange_pub,
@@ -194,6 +393,55 @@ TALER_exchange_offline_signkey_revoke_verify (
}
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * @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;
+};
+
+GNUNET_NETWORK_STRUCT_END
+
+
void
TALER_exchange_offline_signkey_validity_sign (
const struct TALER_ExchangePublicKeyP *exchange_pub,
@@ -247,18 +495,100 @@ TALER_exchange_offline_signkey_validity_verify (
}
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * @brief Information about a denomination key. Denomination keys
+ * are used to sign coins of a certain value into existence.
+ */
+struct TALER_DenominationKeyValidityPS
+{
+
+ /**
+ * Purpose is #TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY.
+ */
+ struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+ /**
+ * The long-term offline master key of the exchange that was
+ * used to create @e signature.
+ *
+ * Note: This member is not strictly required, but here for
+ * backwards-compatibility. If we ever again badly break
+ * compatibility, we might want to remove it.
+ */
+ struct TALER_MasterPublicKeyP master;
+
+ /**
+ * Start time of the validity period for this key.
+ */
+ struct GNUNET_TIME_TimestampNBO start;
+
+ /**
+ * The exchange will sign fresh coins between @e start and this time.
+ * @e expire_withdraw will be somewhat larger than @e start to
+ * ensure a sufficiently large anonymity set, while also allowing
+ * the Exchange to limit the financial damage in case of a key being
+ * compromised. Thus, exchanges with low volume are expected to have a
+ * longer withdraw period (@e expire_withdraw - @e start) than exchanges
+ * with high transaction volume. The period may also differ between
+ * types of coins. A exchange may also have a few denomination keys
+ * with the same value with overlapping validity periods, to address
+ * issues such as clock skew.
+ */
+ struct GNUNET_TIME_TimestampNBO expire_withdraw;
+
+ /**
+ * Coins signed with the denomination key must be spent or refreshed
+ * between @e start and this expiration time. After this time, the
+ * exchange will refuse transactions involving this key as it will
+ * "drop" the table with double-spending information (shortly after)
+ * this time. Note that wallets should refresh coins significantly
+ * before this time to be on the safe side. @e expire_deposit must be
+ * significantly larger than @e expire_withdraw (by months or even
+ * years).
+ */
+ struct GNUNET_TIME_TimestampNBO expire_deposit;
+
+ /**
+ * When do signatures with this denomination 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 expire_legal is expected to be significantly
+ * larger than @e expire_deposit (by a year or more).
+ */
+ struct GNUNET_TIME_TimestampNBO expire_legal;
+
+ /**
+ * The value of the coins signed with this denomination key.
+ */
+ struct TALER_AmountNBO value;
+
+ /**
+ * Fees for the coin.
+ */
+ struct TALER_DenomFeeSetNBOP fees;
+
+ /**
+ * Hash code of the denomination public key. (Used to avoid having
+ * the variable-size RSA key in this struct.)
+ */
+ struct TALER_DenominationHashP denom_hash GNUNET_PACKED;
+
+};
+
+GNUNET_NETWORK_STRUCT_END
+
+
void
TALER_exchange_offline_denom_validity_sign (
- const struct TALER_DenominationHash *h_denom_pub,
+ const struct TALER_DenominationHashP *h_denom_pub,
struct GNUNET_TIME_Timestamp stamp_start,
struct GNUNET_TIME_Timestamp stamp_expire_withdraw,
struct GNUNET_TIME_Timestamp stamp_expire_deposit,
struct GNUNET_TIME_Timestamp stamp_expire_legal,
const struct TALER_Amount *coin_value,
- const struct TALER_Amount *fee_withdraw,
- const struct TALER_Amount *fee_deposit,
- const struct TALER_Amount *fee_refresh,
- const struct TALER_Amount *fee_refund,
+ const struct TALER_DenomFeeSet *fees,
const struct TALER_MasterPrivateKeyP *master_priv,
struct TALER_MasterSignatureP *master_sig)
{
@@ -278,14 +608,8 @@ TALER_exchange_offline_denom_validity_sign (
&issue.master.eddsa_pub);
TALER_amount_hton (&issue.value,
coin_value);
- TALER_amount_hton (&issue.fee_withdraw,
- fee_withdraw);
- TALER_amount_hton (&issue.fee_deposit,
- fee_deposit);
- TALER_amount_hton (&issue.fee_refresh,
- fee_refresh);
- TALER_amount_hton (&issue.fee_refund,
- fee_refund);
+ TALER_denom_fee_set_hton (&issue.fees,
+ fees);
GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
&issue,
&master_sig->eddsa_signature);
@@ -294,16 +618,13 @@ TALER_exchange_offline_denom_validity_sign (
enum GNUNET_GenericReturnValue
TALER_exchange_offline_denom_validity_verify (
- const struct TALER_DenominationHash *h_denom_pub,
+ const struct TALER_DenominationHashP *h_denom_pub,
struct GNUNET_TIME_Timestamp stamp_start,
struct GNUNET_TIME_Timestamp stamp_expire_withdraw,
struct GNUNET_TIME_Timestamp stamp_expire_deposit,
struct GNUNET_TIME_Timestamp stamp_expire_legal,
const struct TALER_Amount *coin_value,
- const struct TALER_Amount *fee_withdraw,
- const struct TALER_Amount *fee_deposit,
- const struct TALER_Amount *fee_refresh,
- const struct TALER_Amount *fee_refund,
+ const struct TALER_DenomFeeSet *fees,
const struct TALER_MasterPublicKeyP *master_pub,
const struct TALER_MasterSignatureP *master_sig)
{
@@ -321,14 +642,8 @@ TALER_exchange_offline_denom_validity_verify (
TALER_amount_hton (&dkv.value,
coin_value);
- TALER_amount_hton (&dkv.fee_withdraw,
- fee_withdraw);
- TALER_amount_hton (&dkv.fee_deposit,
- fee_deposit);
- TALER_amount_hton (&dkv.fee_refresh,
- fee_refresh);
- TALER_amount_hton (&dkv.fee_refund,
- fee_refund);
+ TALER_denom_fee_set_hton (&dkv.fees,
+ fees);
return
GNUNET_CRYPTO_eddsa_verify (
TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY,
@@ -338,9 +653,57 @@ TALER_exchange_offline_denom_validity_verify (
}
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * @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;
+
+ /**
+ * Hash over the conversion URL, all zeros if there
+ * is no conversion URL.
+ */
+ struct GNUNET_HashCode h_conversion_url;
+
+ /**
+ * Hash over the debit restrictions.
+ */
+ struct GNUNET_HashCode h_debit_restrictions;
+
+ /**
+ * Hash over the credit restrictions.
+ */
+ struct GNUNET_HashCode h_credit_restrictions;
+};
+
+GNUNET_NETWORK_STRUCT_END
+
+
void
TALER_exchange_offline_wire_add_sign (
const char *payto_uri,
+ const char *conversion_url,
+ const json_t *debit_restrictions,
+ const json_t *credit_restrictions,
struct GNUNET_TIME_Timestamp now,
const struct TALER_MasterPrivateKeyP *master_priv,
struct TALER_MasterSignatureP *master_sig)
@@ -353,6 +716,14 @@ TALER_exchange_offline_wire_add_sign (
TALER_payto_hash (payto_uri,
&kv.h_payto);
+ if (NULL != conversion_url)
+ GNUNET_CRYPTO_hash (conversion_url,
+ strlen (conversion_url) + 1,
+ &kv.h_conversion_url);
+ TALER_json_hash (debit_restrictions,
+ &kv.h_debit_restrictions);
+ TALER_json_hash (credit_restrictions,
+ &kv.h_credit_restrictions);
GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
&kv,
&master_sig->eddsa_signature);
@@ -362,6 +733,9 @@ TALER_exchange_offline_wire_add_sign (
enum GNUNET_GenericReturnValue
TALER_exchange_offline_wire_add_verify (
const char *payto_uri,
+ const char *conversion_url,
+ const json_t *debit_restrictions,
+ const json_t *credit_restrictions,
struct GNUNET_TIME_Timestamp sign_time,
const struct TALER_MasterPublicKeyP *master_pub,
const struct TALER_MasterSignatureP *master_sig)
@@ -374,6 +748,14 @@ TALER_exchange_offline_wire_add_verify (
TALER_payto_hash (payto_uri,
&aw.h_payto);
+ if (NULL != conversion_url)
+ GNUNET_CRYPTO_hash (conversion_url,
+ strlen (conversion_url) + 1,
+ &aw.h_conversion_url);
+ TALER_json_hash (debit_restrictions,
+ &aw.h_debit_restrictions);
+ TALER_json_hash (credit_restrictions,
+ &aw.h_credit_restrictions);
return
GNUNET_CRYPTO_eddsa_verify (
TALER_SIGNATURE_MASTER_ADD_WIRE,
@@ -383,6 +765,36 @@ TALER_exchange_offline_wire_add_verify (
}
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * @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;
+
+};
+
+GNUNET_NETWORK_STRUCT_END
+
+
void
TALER_exchange_offline_wire_del_sign (
const char *payto_uri,
@@ -428,13 +840,54 @@ TALER_exchange_offline_wire_del_verify (
}
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * @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;
+
+};
+
+GNUNET_NETWORK_STRUCT_END
+
+
void
TALER_exchange_offline_wire_fee_sign (
const char *payment_method,
struct GNUNET_TIME_Timestamp start_time,
struct GNUNET_TIME_Timestamp end_time,
- const struct TALER_Amount *wire_fee,
- const struct TALER_Amount *closing_fee,
+ const struct TALER_WireFeeSet *fees,
const struct TALER_MasterPrivateKeyP *master_priv,
struct TALER_MasterSignatureP *master_sig)
{
@@ -448,10 +901,8 @@ TALER_exchange_offline_wire_fee_sign (
GNUNET_CRYPTO_hash (payment_method,
strlen (payment_method) + 1,
&kv.h_wire_method);
- TALER_amount_hton (&kv.wire_fee,
- wire_fee);
- TALER_amount_hton (&kv.closing_fee,
- closing_fee);
+ TALER_wire_fee_set_hton (&kv.fees,
+ fees);
GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
&kv,
&master_sig->eddsa_signature);
@@ -463,8 +914,7 @@ TALER_exchange_offline_wire_fee_verify (
const char *payment_method,
struct GNUNET_TIME_Timestamp start_time,
struct GNUNET_TIME_Timestamp end_time,
- const struct TALER_Amount *wire_fee,
- const struct TALER_Amount *closing_fee,
+ const struct TALER_WireFeeSet *fees,
const struct TALER_MasterPublicKeyP *master_pub,
const struct TALER_MasterSignatureP *master_sig)
{
@@ -478,10 +928,8 @@ TALER_exchange_offline_wire_fee_verify (
GNUNET_CRYPTO_hash (payment_method,
strlen (payment_method) + 1,
&wf.h_wire_method);
- TALER_amount_hton (&wf.wire_fee,
- wire_fee);
- TALER_amount_hton (&wf.closing_fee,
- closing_fee);
+ TALER_wire_fee_set_hton (&wf.fees,
+ fees);
return
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_WIRE_FEES,
&wf,
@@ -490,16 +938,155 @@ TALER_exchange_offline_wire_fee_verify (
}
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * 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 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;
+
+};
+
+GNUNET_NETWORK_STRUCT_END
+
+
+void
+TALER_exchange_offline_global_fee_sign (
+ struct GNUNET_TIME_Timestamp start_time,
+ struct GNUNET_TIME_Timestamp end_time,
+ const struct TALER_GlobalFeeSet *fees,
+ struct GNUNET_TIME_Relative purse_timeout,
+ struct GNUNET_TIME_Relative history_expiration,
+ uint32_t purse_account_limit,
+ const struct TALER_MasterPrivateKeyP *master_priv,
+ struct TALER_MasterSignatureP *master_sig)
+{
+ struct TALER_MasterGlobalFeePS wf = {
+ .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_GLOBAL_FEES),
+ .purpose.size = htonl (sizeof (wf)),
+ .start_date = GNUNET_TIME_timestamp_hton (start_time),
+ .end_date = GNUNET_TIME_timestamp_hton (end_time),
+ .purse_timeout = GNUNET_TIME_relative_hton (purse_timeout),
+ .history_expiration = GNUNET_TIME_relative_hton (history_expiration),
+ .purse_account_limit = htonl (purse_account_limit)
+ };
+
+ TALER_global_fee_set_hton (&wf.fees,
+ fees);
+ GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
+ &wf,
+ &master_sig->eddsa_signature);
+}
+
+
+enum GNUNET_GenericReturnValue
+TALER_exchange_offline_global_fee_verify (
+ struct GNUNET_TIME_Timestamp start_time,
+ struct GNUNET_TIME_Timestamp end_time,
+ const struct TALER_GlobalFeeSet *fees,
+ struct GNUNET_TIME_Relative purse_timeout,
+ struct GNUNET_TIME_Relative history_expiration,
+ uint32_t purse_account_limit,
+ const struct TALER_MasterPublicKeyP *master_pub,
+ const struct TALER_MasterSignatureP *master_sig)
+{
+ struct TALER_MasterGlobalFeePS wf = {
+ .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_GLOBAL_FEES),
+ .purpose.size = htonl (sizeof (wf)),
+ .start_date = GNUNET_TIME_timestamp_hton (start_time),
+ .end_date = GNUNET_TIME_timestamp_hton (end_time),
+ .purse_timeout = GNUNET_TIME_relative_hton (purse_timeout),
+ .history_expiration = GNUNET_TIME_relative_hton (history_expiration),
+ .purse_account_limit = htonl (purse_account_limit)
+ };
+
+ TALER_global_fee_set_hton (&wf.fees,
+ fees);
+ return
+ GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_GLOBAL_FEES,
+ &wf,
+ &master_sig->eddsa_signature,
+ &master_pub->eddsa_pub);
+}
+
+
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * @brief Signature made by the exchange offline key over the manifest of
+ * an extension.
+ */
+struct TALER_MasterExtensionManifestPS
+{
+ /**
+ * 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 manifests of extensions.
+ */
+ struct TALER_ExtensionManifestsHashP h_manifest GNUNET_PACKED;
+};
+
+GNUNET_NETWORK_STRUCT_END
+
+
void
-TALER_exchange_offline_extension_config_hash_sign (
- const struct TALER_ExtensionConfigHash h_config,
+TALER_exchange_offline_extension_manifests_hash_sign (
+ const struct TALER_ExtensionManifestsHashP *h_manifest,
const struct TALER_MasterPrivateKeyP *master_priv,
struct TALER_MasterSignatureP *master_sig)
{
- struct TALER_MasterExtensionConfigurationPS ec = {
+ struct TALER_MasterExtensionManifestPS ec = {
.purpose.purpose = htonl (TALER_SIGNATURE_MASTER_EXTENSION),
.purpose.size = htonl (sizeof(ec)),
- .h_config = h_config
+ .h_manifest = *h_manifest
};
GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
&ec,
@@ -508,16 +1095,16 @@ TALER_exchange_offline_extension_config_hash_sign (
enum GNUNET_GenericReturnValue
-TALER_exchange_offline_extension_config_hash_verify (
- const struct TALER_ExtensionConfigHash h_config,
+TALER_exchange_offline_extension_manifests_hash_verify (
+ const struct TALER_ExtensionManifestsHashP *h_manifest,
const struct TALER_MasterPublicKeyP *master_pub,
const struct TALER_MasterSignatureP *master_sig
)
{
- struct TALER_MasterExtensionConfigurationPS ec = {
+ struct TALER_MasterExtensionManifestPS ec = {
.purpose.purpose = htonl (TALER_SIGNATURE_MASTER_EXTENSION),
.purpose.size = htonl (sizeof(ec)),
- .h_config = h_config
+ .h_manifest = *h_manifest
};
return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_EXTENSION,
@@ -527,4 +1114,275 @@ TALER_exchange_offline_extension_config_hash_verify (
}
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * @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;
+
+ /**
+ * Hash over the conversion URL, all zeros if there
+ * is no conversion URL.
+ */
+ struct GNUNET_HashCode h_conversion_url;
+
+ /**
+ * Hash over the debit restrictions.
+ */
+ struct GNUNET_HashCode h_debit_restrictions;
+
+ /**
+ * Hash over the credit restrictions.
+ */
+ struct GNUNET_HashCode h_credit_restrictions;
+
+};
+
+GNUNET_NETWORK_STRUCT_END
+
+
+enum GNUNET_GenericReturnValue
+TALER_exchange_wire_signature_check (
+ const char *payto_uri,
+ const char *conversion_url,
+ const json_t *debit_restrictions,
+ const json_t *credit_restrictions,
+ 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);
+ if (NULL != conversion_url)
+ GNUNET_CRYPTO_hash (conversion_url,
+ strlen (conversion_url) + 1,
+ &wd.h_conversion_url);
+ TALER_json_hash (debit_restrictions,
+ &wd.h_debit_restrictions);
+ TALER_json_hash (credit_restrictions,
+ &wd.h_credit_restrictions);
+ 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 char *conversion_url,
+ const json_t *debit_restrictions,
+ const json_t *credit_restrictions,
+ 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);
+ if (NULL != conversion_url)
+ GNUNET_CRYPTO_hash (conversion_url,
+ strlen (conversion_url) + 1,
+ &wd.h_conversion_url);
+ TALER_json_hash (debit_restrictions,
+ &wd.h_debit_restrictions);
+ TALER_json_hash (credit_restrictions,
+ &wd.h_credit_restrictions);
+ GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
+ &wd,
+ &master_sig->eddsa_signature);
+}
+
+
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * Message signed by account to merge a purse into a reserve.
+ */
+struct TALER_PartnerConfigurationPS
+{
+
+ /**
+ * Purpose is #TALER_SIGNATURE_MASTER_PARNTER_DETAILS
+ */
+ struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+ struct TALER_MasterPublicKeyP partner_pub;
+ struct GNUNET_TIME_TimestampNBO start_date;
+ struct GNUNET_TIME_TimestampNBO end_date;
+ struct GNUNET_TIME_RelativeNBO wad_frequency;
+ struct TALER_AmountNBO wad_fee;
+ struct GNUNET_HashCode h_url;
+};
+
+GNUNET_NETWORK_STRUCT_END
+
+
+void
+TALER_exchange_offline_partner_details_sign (
+ const struct TALER_MasterPublicKeyP *partner_pub,
+ struct GNUNET_TIME_Timestamp start_date,
+ struct GNUNET_TIME_Timestamp end_date,
+ struct GNUNET_TIME_Relative wad_frequency,
+ const struct TALER_Amount *wad_fee,
+ const char *partner_base_url,
+ const struct TALER_MasterPrivateKeyP *master_priv,
+ struct TALER_MasterSignatureP *master_sig)
+{
+ struct TALER_PartnerConfigurationPS wd = {
+ .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_PARTNER_DETAILS),
+ .purpose.size = htonl (sizeof (wd)),
+ .partner_pub = *partner_pub,
+ .start_date = GNUNET_TIME_timestamp_hton (start_date),
+ .end_date = GNUNET_TIME_timestamp_hton (end_date),
+ .wad_frequency = GNUNET_TIME_relative_hton (wad_frequency),
+ };
+
+ GNUNET_CRYPTO_hash (partner_base_url,
+ strlen (partner_base_url) + 1,
+ &wd.h_url);
+ TALER_amount_hton (&wd.wad_fee,
+ wad_fee);
+ GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
+ &wd,
+ &master_sig->eddsa_signature);
+}
+
+
+enum GNUNET_GenericReturnValue
+TALER_exchange_offline_partner_details_verify (
+ const struct TALER_MasterPublicKeyP *partner_pub,
+ struct GNUNET_TIME_Timestamp start_date,
+ struct GNUNET_TIME_Timestamp end_date,
+ struct GNUNET_TIME_Relative wad_frequency,
+ const struct TALER_Amount *wad_fee,
+ const char *partner_base_url,
+ const struct TALER_MasterPublicKeyP *master_pub,
+ const struct TALER_MasterSignatureP *master_sig)
+{
+ struct TALER_PartnerConfigurationPS wd = {
+ .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_PARTNER_DETAILS),
+ .purpose.size = htonl (sizeof (wd)),
+ .partner_pub = *partner_pub,
+ .start_date = GNUNET_TIME_timestamp_hton (start_date),
+ .end_date = GNUNET_TIME_timestamp_hton (end_date),
+ .wad_frequency = GNUNET_TIME_relative_hton (wad_frequency),
+ };
+
+ GNUNET_CRYPTO_hash (partner_base_url,
+ strlen (partner_base_url) + 1,
+ &wd.h_url);
+ TALER_amount_hton (&wd.wad_fee,
+ wad_fee);
+ return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_PARTNER_DETAILS,
+ &wd,
+ &master_sig->eddsa_signature,
+ &master_pub->eddsa_pub);
+}
+
+
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * Message signed by account to drain profits
+ * from the escrow account of the exchange.
+ */
+struct TALER_DrainProfitPS
+{
+
+ /**
+ * Purpose is #TALER_SIGNATURE_MASTER_DRAIN_PROFITS
+ */
+ struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+ struct TALER_WireTransferIdentifierRawP wtid;
+ struct GNUNET_TIME_TimestampNBO date;
+ struct TALER_AmountNBO amount;
+ struct GNUNET_HashCode h_section;
+ struct TALER_PaytoHashP h_payto;
+};
+
+GNUNET_NETWORK_STRUCT_END
+
+
+void
+TALER_exchange_offline_profit_drain_sign (
+ const struct TALER_WireTransferIdentifierRawP *wtid,
+ struct GNUNET_TIME_Timestamp date,
+ const struct TALER_Amount *amount,
+ const char *account_section,
+ const char *payto_uri,
+ const struct TALER_MasterPrivateKeyP *master_priv,
+ struct TALER_MasterSignatureP *master_sig)
+{
+ struct TALER_DrainProfitPS wd = {
+ .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_DRAIN_PROFIT),
+ .purpose.size = htonl (sizeof (wd)),
+ .wtid = *wtid,
+ .date = GNUNET_TIME_timestamp_hton (date),
+ };
+
+ GNUNET_CRYPTO_hash (account_section,
+ strlen (account_section) + 1,
+ &wd.h_section);
+ TALER_payto_hash (payto_uri,
+ &wd.h_payto);
+ TALER_amount_hton (&wd.amount,
+ amount);
+ GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
+ &wd,
+ &master_sig->eddsa_signature);
+}
+
+
+enum GNUNET_GenericReturnValue
+TALER_exchange_offline_profit_drain_verify (
+ const struct TALER_WireTransferIdentifierRawP *wtid,
+ struct GNUNET_TIME_Timestamp date,
+ const struct TALER_Amount *amount,
+ const char *account_section,
+ const char *payto_uri,
+ const struct TALER_MasterPublicKeyP *master_pub,
+ const struct TALER_MasterSignatureP *master_sig)
+{
+ struct TALER_DrainProfitPS wd = {
+ .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_DRAIN_PROFIT),
+ .purpose.size = htonl (sizeof (wd)),
+ .wtid = *wtid,
+ .date = GNUNET_TIME_timestamp_hton (date),
+ };
+
+ GNUNET_CRYPTO_hash (account_section,
+ strlen (account_section) + 1,
+ &wd.h_section);
+ TALER_payto_hash (payto_uri,
+ &wd.h_payto);
+ TALER_amount_hton (&wd.amount,
+ amount);
+ return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_DRAIN_PROFIT,
+ &wd,
+ &master_sig->eddsa_signature,
+ &master_pub->eddsa_pub);
+}
+
+
/* end of offline_signatures.c */