diff options
Diffstat (limited to 'src/util/offline_signatures.c')
-rw-r--r-- | src/util/offline_signatures.c | 956 |
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 */ |