commit e5f71e7e97b8cf002d76021b1ff046303b3a45c8
parent 827dcf6d856cf99c7fb0d3cd2577b88ede30f560
Author: Christian Grothoff <christian@grothoff.org>
Date: Mon, 2 Mar 2026 21:36:15 +0100
protocol breaking change for b11169
Diffstat:
30 files changed, 945 insertions(+), 149 deletions(-)
diff --git a/ChangeLog b/ChangeLog
@@ -1,3 +1,10 @@
+Mon Mar 2 07:34:41 PM CET 2026
+ Introducing protocol-breaking change that requires operators
+ to re-sign all of the wire accounts of an exchange. The database
+ migration will automatically deactivate all of the existing
+ accounts, so you MUST manually re-sign everything to keep
+ operating after an upgrade to v1.6.0 -CG
+
Mon Feb 10 09:32:10 AM CET 2025
Releasing GNU Taler Exchange 0.14.5. -CG
diff --git a/bootstrap b/bootstrap
@@ -27,7 +27,7 @@ existence()
}
# Freeze SQL files that must no longer be edited.
-for n in 0001 0002 0003 0004 0005 0006 0007 0008
+for n in 0001 0002 0003 0004 0005 0006 0007 0008 0009
do
chmod -w src/exchangedb/exchange-$n.sql*
chmod -w src/exchangedb/$n-*.sql &> /dev/null || true
diff --git a/src/bank-lib/Makefile.am b/src/bank-lib/Makefile.am
@@ -34,7 +34,7 @@ lib_LTLIBRARIES = \
libtalerfakebank.la
libtalerbank_la_LDFLAGS = \
- -version-info 4:0:0 \
+ -version-info 5:0:1 \
-no-undefined
libtalerbank_la_SOURCES = \
bank_api_account_token.c \
@@ -43,6 +43,7 @@ libtalerbank_la_SOURCES = \
bank_api_common.c bank_api_common.h \
bank_api_credit.c \
bank_api_debit.c \
+ bank_api_helper.c \
bank_api_registration.c \
bank_api_transfer.c \
bank_api_parse.c
diff --git a/src/bank-lib/bank_api_helper.c b/src/bank-lib/bank_api_helper.c
@@ -0,0 +1,85 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2026 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
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ TALER; see the file COPYING. If not, see
+ <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file bank-lib/bank_api_helper.c
+ * @brief convenience functions for the ``struct TALER_BANK_TransferSubject``
+ * @author Christian Grothoff
+ */
+#include "taler/platform.h"
+#include "bank_api_common.h"
+#include <microhttpd.h> /* just for HTTP status codes */
+#include "taler/taler_signatures.h"
+#include "taler/taler_curl_lib.h"
+
+
+void
+TALER_BANK_transfer_subject_copy (
+ struct TALER_BANK_TransferSubject *dst,
+ const struct TALER_BANK_TransferSubject *src)
+{
+ dst->format = src->format;
+
+ switch (src->format)
+ {
+ case TALER_BANK_SUBJECT_FORMAT_SIMPLE:
+ dst->details.simple.credit_amount = src->details.simple.credit_amount;
+ dst->details.simple.subject =
+ (src->details.simple.subject != NULL)
+ ? GNUNET_strdup (src->details.simple.subject)
+ : NULL;
+ return;
+
+ case TALER_BANK_SUBJECT_FORMAT_URI:
+ dst->details.uri.uri =
+ (src->details.uri.uri != NULL)
+ ? GNUNET_strdup (src->details.uri.uri)
+ : NULL;
+ return;
+
+ case TALER_BANK_SUBJECT_FORMAT_CH_QR_BILL:
+ dst->details.ch_qr_bill.credit_amount =
+ src->details.ch_qr_bill.credit_amount;
+ dst->details.ch_qr_bill.qr_reference_number =
+ (src->details.ch_qr_bill.qr_reference_number != NULL)
+ ? GNUNET_strdup (src->details.ch_qr_bill.qr_reference_number)
+ : NULL;
+ return;
+ }
+ GNUNET_break (0);
+}
+
+
+void
+TALER_BANK_transfer_subject_free (
+ struct TALER_BANK_TransferSubject *subject)
+{
+ switch (subject->format)
+ {
+ case TALER_BANK_SUBJECT_FORMAT_SIMPLE:
+ GNUNET_free (subject->details.simple.subject);
+ return;
+
+ case TALER_BANK_SUBJECT_FORMAT_URI:
+ GNUNET_free (subject->details.uri.uri);
+ return;
+
+ case TALER_BANK_SUBJECT_FORMAT_CH_QR_BILL:
+ GNUNET_free (subject->details.ch_qr_bill.qr_reference_number);
+ return;
+ }
+ GNUNET_break (0);
+}
diff --git a/src/bank-lib/bank_api_registration.c b/src/bank-lib/bank_api_registration.c
@@ -93,10 +93,12 @@ parse_transfer_subject (const json_t *subject_json,
"SIMPLE"))
{
struct GNUNET_JSON_Specification spec[] = {
- TALER_JSON_spec_amount_any ("credit_amount",
- &ts->details.simple.credit_amount),
- GNUNET_JSON_spec_string ("subject",
- &ts->details.simple.subject),
+ TALER_JSON_spec_amount_any (
+ "credit_amount",
+ &ts->details.simple.credit_amount),
+ GNUNET_JSON_spec_string (
+ "subject",
+ (const char **) &ts->details.simple.subject),
GNUNET_JSON_spec_end ()
};
@@ -115,8 +117,9 @@ parse_transfer_subject (const json_t *subject_json,
"URI"))
{
struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_string ("uri",
- &ts->details.uri.uri),
+ GNUNET_JSON_spec_string (
+ "uri",
+ (const char **) &ts->details.uri.uri),
GNUNET_JSON_spec_end ()
};
@@ -135,10 +138,12 @@ parse_transfer_subject (const json_t *subject_json,
"CH_QR_BILL"))
{
struct GNUNET_JSON_Specification spec[] = {
- TALER_JSON_spec_amount_any ("credit_amount",
- &ts->details.ch_qr_bill.credit_amount),
- GNUNET_JSON_spec_string ("qr_reference_number",
- &ts->details.ch_qr_bill.qr_reference_number),
+ TALER_JSON_spec_amount_any (
+ "credit_amount",
+ &ts->details.ch_qr_bill.credit_amount),
+ GNUNET_JSON_spec_string (
+ "qr_reference_number",
+ (const char **) &ts->details.ch_qr_bill.qr_reference_number),
GNUNET_JSON_spec_end ()
};
diff --git a/src/exchange-tools/taler-exchange-offline.c b/src/exchange-tools/taler-exchange-offline.c
@@ -1615,6 +1615,8 @@ upload_wire_add (const char *exchange_url,
struct WireAddRequest *war;
const char *err_name;
const char *conversion_url = NULL;
+ const char *open_banking_gateway = NULL;
+ const char *wire_transfer_gateway = NULL;
const char *bank_label = NULL;
int64_t priority = 0;
const json_t *debit_restrictions;
@@ -1628,6 +1630,14 @@ upload_wire_add (const char *exchange_url,
&conversion_url),
NULL),
GNUNET_JSON_spec_mark_optional (
+ TALER_JSON_spec_web_url ("open_banking_gateway",
+ &open_banking_gateway),
+ NULL),
+ GNUNET_JSON_spec_mark_optional (
+ TALER_JSON_spec_web_url ("wire_transfer_gateway",
+ &wire_transfer_gateway),
+ NULL),
+ GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_string ("bank_label",
&bank_label),
NULL),
@@ -1699,15 +1709,21 @@ upload_wire_add (const char *exchange_url,
TALER_EXCHANGE_post_management_wire_create (ctx,
exchange_url,
payto_uri,
- conversion_url,
- debit_restrictions,
- credit_restrictions,
start_time,
&master_sig_add,
&master_sig_wire);
TALER_EXCHANGE_post_management_wire_set_options (
war->h,
TALER_EXCHANGE_post_management_wire_option_bank_label (bank_label),
+ TALER_EXCHANGE_post_management_wire_option_conversion_url (conversion_url),
+ TALER_EXCHANGE_post_management_wire_option_open_banking_gateway (
+ open_banking_gateway),
+ TALER_EXCHANGE_post_management_wire_option_wire_transfer_gateway (
+ wire_transfer_gateway),
+ TALER_EXCHANGE_post_management_wire_option_debit_restrictions (
+ debit_restrictions),
+ TALER_EXCHANGE_post_management_wire_option_credit_restrictions (
+ credit_restrictions),
TALER_EXCHANGE_post_management_wire_option_priority (priority));
TALER_EXCHANGE_post_management_wire_start (war->h,
&wire_add_cb,
@@ -3169,6 +3185,8 @@ do_add_wire (char *const *args)
struct TALER_MasterSignatureP master_sig_wire;
struct GNUNET_TIME_Timestamp now;
const char *conversion_url = NULL;
+ const char *open_banking_gateway = NULL;
+ const char *wire_transfer_gateway = NULL;
const char *bank_label = NULL;
int64_t priority = 0;
json_t *debit_restrictions;
@@ -3263,6 +3281,67 @@ do_add_wire (char *const *args)
num_args++;
continue;
}
+
+ if (0 == strcmp (args[num_args],
+ "open-banking-gateway"))
+ {
+ num_args++;
+ open_banking_gateway = args[num_args];
+ if (NULL == open_banking_gateway)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "'open-banking-gateway' requires an argument\n");
+ global_ret = EXIT_INVALIDARGUMENT;
+ GNUNET_SCHEDULER_shutdown ();
+ json_decref (debit_restrictions);
+ json_decref (credit_restrictions);
+ return;
+ }
+ if (! TALER_is_web_url (open_banking_gateway))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "'open-banking-gateway' must refer to HTTP(S) endpoint, `%s' is invalid\n",
+ open_banking_gateway);
+ global_ret = EXIT_INVALIDARGUMENT;
+ GNUNET_SCHEDULER_shutdown ();
+ json_decref (debit_restrictions);
+ json_decref (credit_restrictions);
+ return;
+ }
+ num_args++;
+ continue;
+ }
+
+ if (0 == strcmp (args[num_args],
+ "wire-transfer-gateway"))
+ {
+ num_args++;
+ wire_transfer_gateway = args[num_args];
+ if (NULL == wire_transfer_gateway)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "'wire-transfer-gateway' requires an argument\n");
+ global_ret = EXIT_INVALIDARGUMENT;
+ GNUNET_SCHEDULER_shutdown ();
+ json_decref (debit_restrictions);
+ json_decref (credit_restrictions);
+ return;
+ }
+ if (! TALER_is_web_url (wire_transfer_gateway))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "'wire-transfer-gateway' must refer to HTTP(S) endpoint, `%s' is invalid\n",
+ wire_transfer_gateway);
+ global_ret = EXIT_INVALIDARGUMENT;
+ GNUNET_SCHEDULER_shutdown ();
+ json_decref (debit_restrictions);
+ json_decref (credit_restrictions);
+ return;
+ }
+ num_args++;
+ continue;
+ }
+
if (0 == strcmp (args[num_args],
"credit-restriction"))
{
@@ -3343,6 +3422,8 @@ do_add_wire (char *const *args)
}
TALER_exchange_offline_wire_add_sign (payto_uri,
conversion_url,
+ open_banking_gateway,
+ wire_transfer_gateway,
debit_restrictions,
credit_restrictions,
now,
@@ -3350,6 +3431,8 @@ do_add_wire (char *const *args)
&master_sig_add);
TALER_exchange_wire_signature_make (payto_uri,
conversion_url,
+ open_banking_gateway,
+ wire_transfer_gateway,
debit_restrictions,
credit_restrictions,
&master_priv,
@@ -3366,6 +3449,12 @@ do_add_wire (char *const *args)
GNUNET_JSON_pack_string ("conversion_url",
conversion_url)),
GNUNET_JSON_pack_allow_null (
+ GNUNET_JSON_pack_string ("open_banking_gateway",
+ open_banking_gateway)),
+ GNUNET_JSON_pack_allow_null (
+ GNUNET_JSON_pack_string ("wire_transfer_gateway",
+ wire_transfer_gateway)),
+ GNUNET_JSON_pack_allow_null (
GNUNET_JSON_pack_string ("bank_label",
bank_label)),
GNUNET_JSON_pack_int64 ("priority",
diff --git a/src/exchange/taler-exchange-httpd.h b/src/exchange/taler-exchange-httpd.h
@@ -154,20 +154,6 @@ extern struct TALER_Amount TEH_tiny_amount;
extern char *TEH_shopping_url;
/**
- * URL where wallets and merchants can request short wire transfer
- * subjects for sending funds to the exchange without having to
- * encode the full public key in the subject. Can be NULL if not
- * supported/available.
- */
-extern char *TEH_wire_transfer_gateway;
-
-/**
- * URL where wallets can find an open banking gateway API to
- * initiate wire transfers to withdraw money from this exchange. Can be NULL.
- */
-extern char *TEH_obg_url;
-
-/**
* Linear STEFAN parameter.
*/
extern float TEH_stefan_lin;
diff --git a/src/exchange/taler-exchange-httpd_config.c b/src/exchange/taler-exchange-httpd_config.c
@@ -45,10 +45,6 @@ TEH_handler_config (struct TEH_RequestContext *rc,
GNUNET_JSON_pack_allow_null (
GNUNET_JSON_pack_string ("shopping_url",
TEH_shopping_url)),
- /* Deprecated in v24 */
- GNUNET_JSON_pack_array_steal (
- "supported_kyc_requirements",
- json_array ()),
GNUNET_JSON_pack_object_steal (
"currency_specification",
TALER_JSON_currency_specs_to_json (TEH_cspec)),
@@ -65,10 +61,6 @@ TEH_handler_config (struct TEH_RequestContext *rc,
GNUNET_JSON_pack_allow_null (
GNUNET_JSON_pack_string ("shopping_url",
TEH_shopping_url)),
- GNUNET_JSON_pack_allow_null (
- GNUNET_JSON_pack_string (
- "open_banking_gateway",
- TEH_obg_url)),
GNUNET_JSON_pack_string (
"implementation",
"urn:net:taler:specs:taler-exchange:c-reference"),
diff --git a/src/exchange/taler-exchange-httpd_config.h b/src/exchange/taler-exchange-httpd_config.h
@@ -41,7 +41,7 @@
*
* Returned via both /config and /keys endpoints.
*/
-#define EXCHANGE_PROTOCOL_VERSION "32:0:10"
+#define EXCHANGE_PROTOCOL_VERSION "33:0:0"
/**
diff --git a/src/exchange/taler-exchange-httpd_keys.c b/src/exchange/taler-exchange-httpd_keys.c
@@ -631,6 +631,8 @@ wire_update_event_cb (void *cls,
* @param cls a `json_t *` array to expand with wire account details
* @param payto_uri the exchange bank account URI to add
* @param conversion_url URL of a conversion service, NULL if there is no conversion
+ * @param open_banking_gateway URL of an open banking gateway, NULL if there is none
+ * @param wire_transfer_gateway URL of a wire transfer gateway, NULL if there is none
* @param debit_restrictions JSON array with debit restrictions on the account
* @param credit_restrictions JSON array with credit restrictions on the account
* @param master_sig master key signature affirming that this is a bank
@@ -639,14 +641,17 @@ wire_update_event_cb (void *cls,
* @param priority priority for ordering bank account labels
*/
static void
-add_wire_account (void *cls,
- const struct TALER_FullPayto payto_uri,
- const char *conversion_url,
- const json_t *debit_restrictions,
- const json_t *credit_restrictions,
- const struct TALER_MasterSignatureP *master_sig,
- const char *bank_label,
- int64_t priority)
+add_wire_account (
+ void *cls,
+ const struct TALER_FullPayto payto_uri,
+ const char *conversion_url,
+ const char *open_banking_gateway,
+ const char *wire_transfer_gateway,
+ const json_t *debit_restrictions,
+ const json_t *credit_restrictions,
+ const struct TALER_MasterSignatureP *master_sig,
+ const char *bank_label,
+ int64_t priority)
{
json_t *a = cls;
@@ -654,6 +659,8 @@ add_wire_account (void *cls,
TALER_exchange_wire_signature_check (
payto_uri,
conversion_url,
+ open_banking_gateway,
+ wire_transfer_gateway,
debit_restrictions,
credit_restrictions,
&TEH_master_public_key,
@@ -667,22 +674,37 @@ add_wire_account (void *cls,
json_array_append_new (
a,
GNUNET_JSON_PACK (
- TALER_JSON_pack_full_payto ("payto_uri",
- payto_uri),
+ TALER_JSON_pack_full_payto (
+ "payto_uri",
+ payto_uri),
GNUNET_JSON_pack_allow_null (
- GNUNET_JSON_pack_string ("conversion_url",
- conversion_url)),
+ GNUNET_JSON_pack_string (
+ "conversion_url",
+ conversion_url)),
GNUNET_JSON_pack_allow_null (
- GNUNET_JSON_pack_string ("bank_label",
- bank_label)),
- GNUNET_JSON_pack_int64 ("priority",
- priority),
- GNUNET_JSON_pack_array_incref ("debit_restrictions",
- (json_t *) debit_restrictions),
- GNUNET_JSON_pack_array_incref ("credit_restrictions",
- (json_t *) credit_restrictions),
- GNUNET_JSON_pack_data_auto ("master_sig",
- master_sig))))
+ GNUNET_JSON_pack_string (
+ "open_banking_gateway",
+ open_banking_gateway)),
+ GNUNET_JSON_pack_allow_null (
+ GNUNET_JSON_pack_string (
+ "wire_transfer_gateway",
+ wire_transfer_gateway)),
+ GNUNET_JSON_pack_allow_null (
+ GNUNET_JSON_pack_string (
+ "bank_label",
+ bank_label)),
+ GNUNET_JSON_pack_int64 (
+ "priority",
+ priority),
+ GNUNET_JSON_pack_array_incref (
+ "debit_restrictions",
+ (json_t *) debit_restrictions),
+ GNUNET_JSON_pack_array_incref (
+ "credit_restrictions",
+ (json_t *) credit_restrictions),
+ GNUNET_JSON_pack_data_auto (
+ "master_sig",
+ master_sig))))
{
GNUNET_break (0); /* out of memory!? */
return;
@@ -2466,14 +2488,6 @@ create_krd (struct TEH_KeyStateHandle *ksh,
GNUNET_JSON_pack_allow_null (
GNUNET_JSON_pack_string ("shopping_url",
TEH_shopping_url)),
- GNUNET_JSON_pack_allow_null (
- GNUNET_JSON_pack_string (
- "open_banking_gateway",
- TEH_obg_url)),
- GNUNET_JSON_pack_allow_null (
- GNUNET_JSON_pack_string (
- "wire_transfer_gateway",
- TEH_wire_transfer_gateway)),
TALER_JSON_pack_amount ("tiny_amount",
&TEH_tiny_amount),
GNUNET_JSON_pack_data_auto ("exchange_pub",
diff --git a/src/exchange/taler-exchange-httpd_management_wire_disable.c b/src/exchange/taler-exchange-httpd_management_wire_disable.c
@@ -117,6 +117,8 @@ del_wire (void *cls,
NULL,
NULL,
NULL,
+ NULL,
+ NULL,
awc->validity_end,
NULL,
NULL,
diff --git a/src/exchange/taler-exchange-httpd_management_wire_enable.c b/src/exchange/taler-exchange-httpd_management_wire_enable.c
@@ -60,6 +60,16 @@ struct AddWireContext
const char *conversion_url;
/**
+ * (optional) address of an open banking gateway service for this account.
+ */
+ const char *open_banking_gateway;
+
+ /**
+ * (optional) address of a wire transfer gateway service for this account.
+ */
+ const char *wire_transfer_gateway;
+
+ /**
* Restrictions imposed when crediting this account.
*/
const json_t *credit_restrictions;
@@ -140,6 +150,8 @@ add_wire (void *cls,
qs = TEH_plugin->insert_wire (TEH_plugin->cls,
awc->payto_uri,
awc->conversion_url,
+ awc->open_banking_gateway,
+ awc->wire_transfer_gateway,
awc->debit_restrictions,
awc->credit_restrictions,
awc->validity_start,
@@ -150,6 +162,8 @@ add_wire (void *cls,
qs = TEH_plugin->update_wire (TEH_plugin->cls,
awc->payto_uri,
awc->conversion_url,
+ awc->open_banking_gateway,
+ awc->wire_transfer_gateway,
awc->debit_restrictions,
awc->credit_restrictions,
awc->validity_start,
@@ -181,22 +195,30 @@ TEH_handler_management_post_wire (
.conversion_url = NULL
};
struct GNUNET_JSON_Specification spec[] = {
+ TALER_JSON_spec_full_payto_uri ("payto_uri",
+ &awc.payto_uri),
GNUNET_JSON_spec_fixed_auto ("master_sig_wire",
&awc.master_sig_wire),
GNUNET_JSON_spec_fixed_auto ("master_sig_add",
&awc.master_sig_add),
- TALER_JSON_spec_full_payto_uri ("payto_uri",
- &awc.payto_uri),
+ GNUNET_JSON_spec_timestamp ("validity_start",
+ &awc.validity_start),
GNUNET_JSON_spec_mark_optional (
TALER_JSON_spec_web_url ("conversion_url",
&awc.conversion_url),
NULL),
+ GNUNET_JSON_spec_mark_optional (
+ TALER_JSON_spec_web_url ("open_banking_gateway",
+ &awc.open_banking_gateway),
+ NULL),
+ GNUNET_JSON_spec_mark_optional (
+ TALER_JSON_spec_web_url ("wire_transfer_gateway",
+ &awc.wire_transfer_gateway),
+ NULL),
GNUNET_JSON_spec_array_const ("credit_restrictions",
&awc.credit_restrictions),
GNUNET_JSON_spec_array_const ("debit_restrictions",
&awc.debit_restrictions),
- GNUNET_JSON_spec_timestamp ("validity_start",
- &awc.validity_start),
GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_string ("bank_label",
&awc.bank_label),
@@ -242,6 +264,8 @@ TEH_handler_management_post_wire (
TALER_exchange_offline_wire_add_verify (
awc.payto_uri,
awc.conversion_url,
+ awc.open_banking_gateway,
+ awc.wire_transfer_gateway,
awc.debit_restrictions,
awc.credit_restrictions,
awc.validity_start,
@@ -261,6 +285,8 @@ TEH_handler_management_post_wire (
TALER_exchange_wire_signature_check (
awc.payto_uri,
awc.conversion_url,
+ awc.open_banking_gateway,
+ awc.wire_transfer_gateway,
awc.debit_restrictions,
awc.credit_restrictions,
&TEH_master_public_key,
diff --git a/src/exchangedb/exchange-0009.sql b/src/exchangedb/exchange-0009.sql
@@ -0,0 +1,44 @@
+--
+-- This file is part of TALER
+-- Copyright (C) 2026 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
+-- Foundation; either version 3, or (at your option) any later version.
+--
+-- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+-- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License along with
+-- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+--
+
+BEGIN;
+
+SELECT _v.register_patch('exchange-0009', NULL, NULL);
+
+SET search_path TO exchange;
+
+ALTER TABLE wire_accounts
+ ADD COLUMN open_banking_gateway
+ TEXT DEFAULT (NULL)
+ ,ADD COLUMN wire_transfer_gateway
+ TEXT DEFAULT (NULL)
+ ,ADD COLUMN sig_version
+ INT4 DEFAULT 33;
+COMMENT ON COLUMN wire_accounts.open_banking_gateway
+ IS 'URL of an open banking gateway that can be used to initiate wire transfers to this account; NULL if there is no such service.';
+COMMENT ON COLUMN wire_accounts.wire_transfer_gateway
+ IS 'URL of a wire transfer gateway that can be used to obtain (short) wire transfer subjects; NULL if there is no such service.';
+COMMENT ON COLUMN wire_accounts.sig_version
+ IS 'Protocol version used by the master_sig in this column. Used to tell which algorithm is needed to verify the signature.';
+
+-- The master_sig changes in protocol v33, hence deactivate all old
+-- signatures/accounts.
+UPDATE wire_accounts
+ SET is_active=FALSE
+ ,sig_version=32;
+
+
+COMMIT;
diff --git a/src/exchangedb/pg_get_wire_accounts.c b/src/exchangedb/pg_get_wire_accounts.c
@@ -67,6 +67,8 @@ get_wire_accounts_cb (void *cls,
{
struct TALER_FullPayto payto_uri;
char *conversion_url = NULL;
+ char *open_banking_gateway = NULL;
+ char *wire_transfer_gateway = NULL;
json_t *debit_restrictions = NULL;
json_t *credit_restrictions = NULL;
struct TALER_MasterSignatureP master_sig;
@@ -80,6 +82,14 @@ get_wire_accounts_cb (void *cls,
&conversion_url),
NULL),
GNUNET_PQ_result_spec_allow_null (
+ GNUNET_PQ_result_spec_string ("open_banking_gateway",
+ &open_banking_gateway),
+ NULL),
+ GNUNET_PQ_result_spec_allow_null (
+ GNUNET_PQ_result_spec_string ("wire_transfer_gateway",
+ &wire_transfer_gateway),
+ NULL),
+ GNUNET_PQ_result_spec_allow_null (
GNUNET_PQ_result_spec_string ("bank_label",
&bank_label),
NULL),
@@ -120,6 +130,8 @@ get_wire_accounts_cb (void *cls,
ctx->cb (ctx->cb_cls,
payto_uri,
conversion_url,
+ open_banking_gateway,
+ wire_transfer_gateway,
debit_restrictions,
credit_restrictions,
&master_sig,
@@ -151,6 +163,8 @@ TEH_PG_get_wire_accounts (void *cls,
"SELECT"
" payto_uri"
",conversion_url"
+ ",open_banking_gateway"
+ ",wire_transfer_gateway"
",debit_restrictions::TEXT"
",credit_restrictions::TEXT"
",master_sig"
diff --git a/src/exchangedb/pg_insert_wire.c b/src/exchangedb/pg_insert_wire.c
@@ -31,6 +31,8 @@ TEH_PG_insert_wire (
void *cls,
const struct TALER_FullPayto payto_uri,
const char *conversion_url,
+ const char *open_banking_gateway,
+ const char *wire_transfer_gateway,
const json_t *debit_restrictions,
const json_t *credit_restrictions,
struct GNUNET_TIME_Timestamp start_date,
@@ -52,6 +54,12 @@ TEH_PG_insert_wire (
? GNUNET_PQ_query_param_null ()
: GNUNET_PQ_query_param_string (bank_label),
GNUNET_PQ_query_param_int64 (&priority),
+ NULL == open_banking_gateway
+ ? GNUNET_PQ_query_param_null ()
+ : GNUNET_PQ_query_param_string (open_banking_gateway),
+ NULL == wire_transfer_gateway
+ ? GNUNET_PQ_query_param_null ()
+ : GNUNET_PQ_query_param_string (wire_transfer_gateway),
GNUNET_PQ_query_param_end
};
@@ -67,8 +75,10 @@ TEH_PG_insert_wire (
",last_change"
",bank_label"
",priority"
+ ",open_banking_gateway"
+ ",wire_transfer_gateway"
") VALUES "
- "($1,$2,$3::TEXT::JSONB,$4::TEXT::JSONB,$5,true,$6,$7,$8);");
+ "($1,$2,$3::TEXT::JSONB,$4::TEXT::JSONB,$5,true,$6,$7,$8,$9,$10);");
return GNUNET_PQ_eval_prepared_non_select (pg->conn,
"insert_wire",
params);
diff --git a/src/exchangedb/pg_insert_wire.h b/src/exchangedb/pg_insert_wire.h
@@ -32,6 +32,8 @@
* @param cls closure
* @param payto_uri wire account of the exchange
* @param conversion_url URL of a conversion service, NULL if there is no conversion
+ * @param open_banking_gateway open banking gateway service, NULL if unavailable
+ * @param wire_transfer_gateway wire transfer gateway service, NULL if unavailable
* @param debit_restrictions JSON array with debit restrictions on the account
* @param credit_restrictions JSON array with credit restrictions on the account
* @param start_date date when the account was added by the offline system
@@ -46,6 +48,8 @@ enum GNUNET_DB_QueryStatus
TEH_PG_insert_wire (void *cls,
const struct TALER_FullPayto payto_uri,
const char *conversion_url,
+ const char *open_banking_gateway,
+ const char *wire_transfer_gateway,
const json_t *debit_restrictions,
const json_t *credit_restrictions,
struct GNUNET_TIME_Timestamp start_date,
diff --git a/src/exchangedb/pg_update_wire.c b/src/exchangedb/pg_update_wire.c
@@ -31,6 +31,8 @@ TEH_PG_update_wire (
void *cls,
const struct TALER_FullPayto payto_uri,
const char *conversion_url,
+ const char *open_banking_gateway,
+ const char *wire_transfer_gateway,
const json_t *debit_restrictions,
const json_t *credit_restrictions,
struct GNUNET_TIME_Timestamp change_date,
@@ -60,6 +62,12 @@ TEH_PG_update_wire (
? GNUNET_PQ_query_param_null ()
: GNUNET_PQ_query_param_string (bank_label),
GNUNET_PQ_query_param_int64 (&priority),
+ NULL == open_banking_gateway
+ ? GNUNET_PQ_query_param_null ()
+ : GNUNET_PQ_query_param_string (open_banking_gateway),
+ NULL == wire_transfer_gateway
+ ? GNUNET_PQ_query_param_null ()
+ : GNUNET_PQ_query_param_string (wire_transfer_gateway),
GNUNET_PQ_query_param_end
};
@@ -75,6 +83,8 @@ TEH_PG_update_wire (
" ,master_sig=$7"
" ,bank_label=$8"
" ,priority=$9"
+ " ,open_banking_gateway=$10"
+ " ,wire_transfer_gateway=$11"
" WHERE payto_uri=$1");
return GNUNET_PQ_eval_prepared_non_select (pg->conn,
"update_wire",
diff --git a/src/exchangedb/pg_update_wire.h b/src/exchangedb/pg_update_wire.h
@@ -32,6 +32,8 @@
* @param cls closure
* @param payto_uri account the update is about
* @param conversion_url URL of a conversion service, NULL if there is no conversion
+ * @param open_banking_gateway open banking gateway service, NULL if unavailable
+ * @param wire_transfer_gateway wire transfer gateway service, NULL if unavailable
* @param debit_restrictions JSON array with debit restrictions on the account; NULL allowed if not @a enabled
* @param credit_restrictions JSON array with credit restrictions on the account; NULL allowed if not @a enabled
* @param change_date date when the account status was last changed
@@ -46,6 +48,8 @@ enum GNUNET_DB_QueryStatus
TEH_PG_update_wire (void *cls,
const struct TALER_FullPayto payto_uri,
const char *conversion_url,
+ const char *open_banking_gateway,
+ const char *wire_transfer_gateway,
const json_t *debit_restrictions,
const json_t *credit_restrictions,
struct GNUNET_TIME_Timestamp change_date,
diff --git a/src/include/taler/taler-exchange/get-keys.h b/src/include/taler/taler-exchange/get-keys.h
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2014-2025 Taler Systems SA
+ Copyright (C) 2014-2026 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License as published by the Free Software
@@ -416,6 +416,20 @@ struct TALER_EXCHANGE_WireAccount
char *conversion_url;
/**
+ * Open banking gateway base URL for wallet-initiated wire
+ * transfers. NULL if not configured.
+ * @since protocol v33.
+ */
+ char *open_banking_gateway;
+
+ /**
+ * Wire transfer gateway base URL for short wire transfer
+ * subjects. NULL if not configured.
+ * @since protocol v33.
+ */
+ char *wire_transfer_gateway;
+
+ /**
* Array of restrictions that apply when crediting
* this account.
*/
@@ -580,20 +594,6 @@ struct TALER_EXCHANGE_Keys
char *shopping_url;
/**
- * Open banking gateway base URL for wallet-initiated wire
- * transfers. NULL if not configured.
- * @since protocol v30.
- */
- char *open_banking_gateway;
-
- /**
- * Wire transfer gateway base URL for short wire transfer
- * subjects. NULL if not configured.
- * @since protocol v33.
- */
- char *wire_transfer_gateway;
-
- /**
* Bank-specific compliance language hint for wallets.
* NULL if not configured.
* @since protocol v24.
diff --git a/src/include/taler/taler-exchange/post-management-wire.h b/src/include/taler/taler-exchange/post-management-wire.h
@@ -44,7 +44,37 @@ enum TALER_EXCHANGE_PostManagementWireOption
* Priority for ordering the bank accounts when displaying to users.
* If not set, defaults to 0.
*/
- TALER_EXCHANGE_POST_MANAGEMENT_WIRE_OPTION_PRIORITY
+ TALER_EXCHANGE_POST_MANAGEMENT_WIRE_OPTION_PRIORITY,
+
+ /**
+ * URL of conversion service to use.
+ * If not set, no conversion is used.
+ */
+ TALER_EXCHANGE_POST_MANAGEMENT_WIRE_OPTION_CONVERSION_URL,
+
+ /**
+ * Open banking gateway that could be used.
+ * If not set, no open banking gateway is available.
+ */
+ TALER_EXCHANGE_POST_MANAGEMENT_WIRE_OPTION_OPEN_BANKING_GATEWAY,
+
+ /**
+ * Wire transfer gateway service URL for short wire transfer subjects.
+ * If not set, no wire transfer gateway is used.
+ */
+ TALER_EXCHANGE_POST_MANAGEMENT_WIRE_OPTION_WIRE_TRANSFER_GATEWAY,
+
+ /**
+ * Set of credit restrictions to apply.
+ * If not set, no credit restrictions apply.
+ */
+ TALER_EXCHANGE_POST_MANAGEMENT_WIRE_OPTION_CREDIT_RESTRICTIONS,
+
+ /**
+ * Set of debit restrictions to apply.
+ * If not set, no debit restrictions apply.
+ */
+ TALER_EXCHANGE_POST_MANAGEMENT_WIRE_OPTION_DEBIT_RESTRICTIONS
};
@@ -73,6 +103,41 @@ struct TALER_EXCHANGE_PostManagementWireOptionValue
/**
* Value if @e option is
+ * #TALER_EXCHANGE_POST_MANAGEMENT_WIRE_OPTION_CONVERSION_URL.
+ * May be NULL.
+ */
+ const char *conversion_url;
+
+ /**
+ * Value if @e option is
+ * #TALER_EXCHANGE_POST_MANAGEMENT_WIRE_OPTION_OPEN_BANKING_GATEWAY.
+ * May be NULL.
+ */
+ const char *open_banking_gateway;
+
+ /**
+ * Value if @e option is
+ * #TALER_EXCHANGE_POST_MANAGEMENT_WIRE_OPTION_WIRE_TRANSFER_GATEWAY.
+ * May be NULL.
+ */
+ const char *wire_transfer_gateway;
+
+ /**
+ * Value if @e option is
+ * #TALER_EXCHANGE_POST_MANAGEMENT_WIRE_OPTION_CREDIT_RESTRICTIONS.
+ * May be NULL.
+ */
+ const json_t *credit_restrictions;
+
+ /**
+ * Value if @e option is
+ * #TALER_EXCHANGE_POST_MANAGEMENT_WIRE_OPTION_DEBIT_RESTRICTIONS.
+ * May be NULL.
+ */
+ const json_t *debit_restrictions;
+
+ /**
+ * Value if @e option is
* #TALER_EXCHANGE_POST_MANAGEMENT_WIRE_OPTION_PRIORITY.
*/
int64_t priority;
@@ -95,9 +160,6 @@ struct TALER_EXCHANGE_PostManagementWireHandle;
* @param ctx the context
* @param url HTTP base URL for the exchange
* @param payto_uri RFC 8905 URI of the exchange's bank account
- * @param conversion_url URL of the conversion service, or NULL if none
- * @param debit_restrictions JSON encoding of debit restrictions on the account; see AccountRestriction in the spec
- * @param credit_restrictions JSON encoding of credit restrictions on the account; see AccountRestriction in the spec
* @param validity_start when was this decided?
* @param master_sig1 signature affirming the wire addition
* of purpose #TALER_SIGNATURE_MASTER_ADD_WIRE
@@ -110,9 +172,6 @@ TALER_EXCHANGE_post_management_wire_create (
struct GNUNET_CURL_Context *ctx,
const char *url,
const struct TALER_FullPayto payto_uri,
- const char *conversion_url,
- const json_t *debit_restrictions,
- const json_t *credit_restrictions,
struct GNUNET_TIME_Timestamp validity_start,
const struct TALER_MasterSignatureP *master_sig1,
const struct TALER_MasterSignatureP *master_sig2);
@@ -142,6 +201,7 @@ TALER_EXCHANGE_post_management_wire_create (
.details.bank_label = (l) \
}
+
/**
* Set the priority for ordering the bank accounts.
*
@@ -157,6 +217,79 @@ TALER_EXCHANGE_post_management_wire_create (
/**
+ * Set the conversion URL for the wire account.
+ *
+ * @param u the conversion service URL string, or NULL for no conversion
+ * @return representation of the option as a struct TALER_EXCHANGE_PostManagementWireOptionValue
+ */
+#define TALER_EXCHANGE_post_management_wire_option_conversion_url(u) \
+ (const struct TALER_EXCHANGE_PostManagementWireOptionValue) \
+ { \
+ .option = TALER_EXCHANGE_POST_MANAGEMENT_WIRE_OPTION_CONVERSION_URL, \
+ .details.conversion_url = (u) \
+ }
+
+
+/**
+ * Set the open banking gateway for the wire account.
+ *
+ * @param g the open banking gateway URL string, or NULL for no gateway
+ * @return representation of the option as a struct TALER_EXCHANGE_PostManagementWireOptionValue
+ */
+#define TALER_EXCHANGE_post_management_wire_option_open_banking_gateway(g) \
+ (const struct TALER_EXCHANGE_PostManagementWireOptionValue) \
+ { \
+ .option = \
+ TALER_EXCHANGE_POST_MANAGEMENT_WIRE_OPTION_OPEN_BANKING_GATEWAY, \
+ .details.open_banking_gateway = (g) \
+ }
+
+
+/**
+ * Set the wire transfer gateway for the wire account.
+ *
+ * @param g the wire transfer gateway URL string, or NULL for no gateway
+ * @return representation of the option as a struct TALER_EXCHANGE_PostManagementWireOptionValue
+ */
+#define TALER_EXCHANGE_post_management_wire_option_wire_transfer_gateway(g) \
+ (const struct TALER_EXCHANGE_PostManagementWireOptionValue) \
+ { \
+ .option = \
+ TALER_EXCHANGE_POST_MANAGEMENT_WIRE_OPTION_WIRE_TRANSFER_GATEWAY, \
+ .details.wire_transfer_gateway = (g) \
+ }
+
+
+/**
+ * Set the credit restrictions for the wire account.
+ *
+ * @param r JSON encoding of the credit restrictions, or NULL for no restrictions
+ * @return representation of the option as a struct TALER_EXCHANGE_PostManagementWireOptionValue
+ */
+#define TALER_EXCHANGE_post_management_wire_option_credit_restrictions(r) \
+ (const struct TALER_EXCHANGE_PostManagementWireOptionValue) \
+ { \
+ .option = \
+ TALER_EXCHANGE_POST_MANAGEMENT_WIRE_OPTION_CREDIT_RESTRICTIONS, \
+ .details.credit_restrictions = (r) \
+ }
+
+
+/**
+ * Set the debit restrictions for the wire account.
+ *
+ * @param r JSON encoding of the debit restrictions, or NULL for no restrictions
+ * @return representation of the option as a struct TALER_EXCHANGE_PostManagementWireOptionValue
+ */
+#define TALER_EXCHANGE_post_management_wire_option_debit_restrictions(r) \
+ (const struct TALER_EXCHANGE_PostManagementWireOptionValue) \
+ { \
+ .option = \
+ TALER_EXCHANGE_POST_MANAGEMENT_WIRE_OPTION_DEBIT_RESTRICTIONS, \
+ .details.debit_restrictions = (r) \
+ }
+
+/**
* Set the requested options for the operation.
*
* If any option fails, other options may or may not be applied.
diff --git a/src/include/taler/taler_bank_service.h b/src/include/taler/taler_bank_service.h
@@ -1120,7 +1120,7 @@ struct TALER_BANK_TransferSubject
/**
* Encoded string containing the key or derived short subject.
*/
- const char *subject;
+ char *subject;
} simple;
@@ -1133,7 +1133,7 @@ struct TALER_BANK_TransferSubject
/**
* Prepared-payment confirmation URI.
*/
- const char *uri;
+ char *uri;
} uri;
@@ -1151,7 +1151,7 @@ struct TALER_BANK_TransferSubject
/**
* 27-digit QR Reference Number (NUL-terminated string).
*/
- const char *qr_reference_number;
+ char *qr_reference_number;
} ch_qr_bill;
@@ -1161,6 +1161,28 @@ struct TALER_BANK_TransferSubject
/**
+ * Make a deep copy of @a src to @a dst.
+ *
+ * @param[out] dst copy to initialize
+ * @param src source to copy from
+ */
+void
+TALER_BANK_transfer_subject_copy (
+ struct TALER_BANK_TransferSubject *dst,
+ const struct TALER_BANK_TransferSubject *src);
+
+
+/**
+ * Free memory allocated inside of @a subject, but not @a subject itself
+ *
+ * @param[in,out] subject memory to free
+ */
+void
+TALER_BANK_transfer_subject_free (
+ struct TALER_BANK_TransferSubject *subject);
+
+
+/**
* Response details for a /registration POST request.
*/
struct TALER_BANK_RegistrationResponse
diff --git a/src/include/taler/taler_crypto_lib.h b/src/include/taler/taler_crypto_lib.h
@@ -6656,6 +6656,8 @@ TALER_exchange_offline_global_fee_verify (
*
* @param payto_uri bank account
* @param conversion_url URL of the conversion service, or NULL if none
+ * @param open_banking_gateway open banking gateway service, NULL if unavailable
+ * @param wire_transfer_gateway wire transfer gateway service, NULL if unavailable
* @param debit_restrictions JSON encoding of debit restrictions on the account; see AccountRestriction in the spec
* @param credit_restrictions JSON encoding of credit restrictions on the account; see AccountRestriction in the spec
* @param now timestamp to use for the signature (rounded)
@@ -6666,6 +6668,8 @@ void
TALER_exchange_offline_wire_add_sign (
const struct TALER_FullPayto payto_uri,
const char *conversion_url,
+ const char *open_banking_gateway,
+ const char *wire_transfer_gateway,
const json_t *debit_restrictions,
const json_t *credit_restrictions,
struct GNUNET_TIME_Timestamp now,
@@ -6678,6 +6682,8 @@ TALER_exchange_offline_wire_add_sign (
*
* @param payto_uri bank account
* @param conversion_url URL of the conversion service, or NULL if none
+ * @param open_banking_gateway open banking gateway service, NULL if unavailable
+ * @param wire_transfer_gateway wire transfer gateway service, NULL if unavailable
* @param debit_restrictions JSON encoding of debit restrictions on the account; see AccountRestriction in the spec
* @param credit_restrictions JSON encoding of credit restrictions on the account; see AccountRestriction in the spec
* @param sign_time timestamp when signature was created
@@ -6689,6 +6695,31 @@ enum GNUNET_GenericReturnValue
TALER_exchange_offline_wire_add_verify (
const struct TALER_FullPayto payto_uri,
const char *conversion_url,
+ const char *open_banking_gateway,
+ const char *wire_transfer_gateway,
+ 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);
+
+
+/**
+ * Verify wire account addition signature for legacy (pre v33) APIs.
+ *
+ * @param payto_uri bank account
+ * @param conversion_url URL of the conversion service, or NULL if none
+ * @param debit_restrictions JSON encoding of debit restrictions on the account; see AccountRestriction in the spec
+ * @param credit_restrictions JSON encoding of credit restrictions on the account; see AccountRestriction in the spec
+ * @param sign_time timestamp when signature was created
+ * @param master_pub public key to verify against
+ * @param master_sig the signature the signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_offline_wire_add_verify_32 (
+ const struct TALER_FullPayto payto_uri,
+ const char *conversion_url,
const json_t *debit_restrictions,
const json_t *credit_restrictions,
struct GNUNET_TIME_Timestamp sign_time,
@@ -6734,6 +6765,8 @@ TALER_exchange_offline_wire_del_verify (
*
* @param payto_uri URI that is signed
* @param conversion_url URL of the conversion service, or NULL if none
+ * @param open_banking_gateway open banking gateway service, NULL if unavailable
+ * @param wire_transfer_gateway wire transfer gateway service, NULL if unavailable
* @param debit_restrictions JSON encoding of debit restrictions on the account; see AccountRestriction in the spec
* @param credit_restrictions JSON encoding of credit restrictions on the account; see AccountRestriction in the spec
* @param master_pub master public key of the exchange
@@ -6744,6 +6777,29 @@ enum GNUNET_GenericReturnValue
TALER_exchange_wire_signature_check (
const struct TALER_FullPayto payto_uri,
const char *conversion_url,
+ const char *open_banking_gateway,
+ const char *wire_transfer_gateway,
+ const json_t *debit_restrictions,
+ const json_t *credit_restrictions,
+ const struct TALER_MasterPublicKeyP *master_pub,
+ const struct TALER_MasterSignatureP *master_sig);
+
+
+/**
+ * Check the signature in @a master_sig. Pre v33 version.
+ *
+ * @param payto_uri URI that is signed
+ * @param conversion_url URL of the conversion service, or NULL if none
+ * @param debit_restrictions JSON encoding of debit restrictions on the account; see AccountRestriction in the spec
+ * @param credit_restrictions JSON encoding of credit restrictions on the account; see AccountRestriction in the spec
+ * @param master_pub master public key of the exchange
+ * @param master_sig signature of the exchange
+ * @return #GNUNET_OK if signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_wire_signature_check32 (
+ const struct TALER_FullPayto payto_uri,
+ const char *conversion_url,
const json_t *debit_restrictions,
const json_t *credit_restrictions,
const struct TALER_MasterPublicKeyP *master_pub,
@@ -6755,6 +6811,8 @@ TALER_exchange_wire_signature_check (
*
* @param payto_uri account specification
* @param conversion_url URL of the conversion service, or NULL if none
+ * @param open_banking_gateway open banking gateway service, NULL if unavailable
+ * @param wire_transfer_gateway wire transfer gateway service, NULL if unavailable
* @param debit_restrictions JSON encoding of debit restrictions on the account; see AccountRestriction in the spec
* @param credit_restrictions JSON encoding of credit restrictions on the account; see AccountRestriction in the spec
* @param master_priv private key to sign with
@@ -6764,6 +6822,8 @@ void
TALER_exchange_wire_signature_make (
const struct TALER_FullPayto payto_uri,
const char *conversion_url,
+ const char *open_banking_gateway,
+ const char *wire_transfer_gateway,
const json_t *debit_restrictions,
const json_t *credit_restrictions,
const struct TALER_MasterPrivateKeyP *master_priv,
diff --git a/src/include/taler/taler_exchangedb_plugin.h b/src/include/taler/taler_exchangedb_plugin.h
@@ -3276,6 +3276,8 @@ typedef enum GNUNET_GenericReturnValue
* @param cls closure
* @param payto_uri the exchange bank account URI
* @param conversion_url URL of a conversion service, NULL if there is no conversion
+ * @param open_banking_gateway open banking gateway service, NULL if unavailable
+ * @param wire_transfer_gateway wire transfer gateway service, NULL if unavailable
* @param debit_restrictions JSON array with debit restrictions on the account
* @param credit_restrictions JSON array with credit restrictions on the account
* @param master_sig master key signature affirming that this is a bank
@@ -3288,6 +3290,8 @@ typedef void
void *cls,
const struct TALER_FullPayto payto_uri,
const char *conversion_url,
+ const char *open_banking_gateway,
+ const char *wire_transfer_gateway,
const json_t *debit_restrictions,
const json_t *credit_restrictions,
const struct TALER_MasterSignatureP *master_sig,
@@ -6148,6 +6152,8 @@ struct TALER_EXCHANGEDB_Plugin
* @param cls closure
* @param payto_uri wire account of the exchange
* @param conversion_url URL of a conversion service, NULL if there is no conversion
+ * @param open_banking_gateway open banking gateway service, NULL if unavailable
+ * @param wire_transfer_gateway wire transfer gateway service, NULL if unavailable
* @param debit_restrictions JSON array with debit restrictions on the account
* @param credit_restrictions JSON array with credit restrictions on the account
* @param start_date date when the account was added by the offline system
@@ -6162,6 +6168,8 @@ struct TALER_EXCHANGEDB_Plugin
(*insert_wire)(void *cls,
const struct TALER_FullPayto payto_uri,
const char *conversion_url,
+ const char *open_banking_gateway,
+ const char *wire_transfer_gateway,
const json_t *debit_restrictions,
const json_t *credit_restrictions,
struct GNUNET_TIME_Timestamp start_date,
@@ -6176,6 +6184,8 @@ struct TALER_EXCHANGEDB_Plugin
* @param cls closure
* @param payto_uri account the update is about
* @param conversion_url URL of a conversion service, NULL if there is no conversion
+ * @param open_banking_gateway open banking gateway service, NULL if unavailable
+ * @param wire_transfer_gateway wire transfer gateway service, NULL if unavailable
* @param debit_restrictions JSON array with debit restrictions on the account; NULL allowed if not @a enabled
* @param credit_restrictions JSON array with credit restrictions on the account; NULL allowed if not @a enabled
* @param change_date date when the account status was last changed
@@ -6190,6 +6200,8 @@ struct TALER_EXCHANGEDB_Plugin
(*update_wire)(void *cls,
const struct TALER_FullPayto payto_uri,
const char *conversion_url,
+ const char *open_banking_gateway,
+ const char *wire_transfer_gateway,
const json_t *debit_restrictions,
const json_t *credit_restrictions,
struct GNUNET_TIME_Timestamp change_date,
diff --git a/src/lib/exchange_api_common.c b/src/lib/exchange_api_common.c
@@ -516,6 +516,8 @@ TALER_EXCHANGE_parse_accounts (
struct TALER_EXCHANGE_WireAccount *wa = &was[i];
struct TALER_FullPayto payto_uri;
const char *conversion_url = NULL;
+ const char *open_banking_gateway = NULL;
+ const char *wire_transfer_gateway = NULL;
const char *bank_label = NULL;
int64_t priority = 0;
const json_t *credit_restrictions;
@@ -528,6 +530,14 @@ TALER_EXCHANGE_parse_accounts (
&conversion_url),
NULL),
GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_string ("open_banking_gateway",
+ &open_banking_gateway),
+ NULL),
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_string ("wire_transfer_gateway",
+ &wire_transfer_gateway),
+ NULL),
+ GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_int64 ("priority",
&priority),
NULL),
@@ -557,14 +567,26 @@ TALER_EXCHANGE_parse_accounts (
return GNUNET_SYSERR;
}
if ( (NULL != master_pub) &&
- (GNUNET_OK !=
- TALER_exchange_wire_signature_check (
- payto_uri,
- conversion_url,
- debit_restrictions,
- credit_restrictions,
- master_pub,
- &wa->master_sig)) )
+ (! ( ( (NULL == open_banking_gateway) &&
+ (NULL == wire_transfer_gateway) &&
+ (GNUNET_OK ==
+ TALER_exchange_wire_signature_check32 (
+ payto_uri,
+ conversion_url,
+ debit_restrictions,
+ credit_restrictions,
+ master_pub,
+ &wa->master_sig)) ) ||
+ (GNUNET_OK ==
+ TALER_exchange_wire_signature_check (
+ payto_uri,
+ conversion_url,
+ open_banking_gateway,
+ wire_transfer_gateway,
+ debit_restrictions,
+ credit_restrictions,
+ master_pub,
+ &wa->master_sig)) ) ) )
{
/* bogus reply */
GNUNET_break_op (0);
@@ -588,6 +610,10 @@ TALER_EXCHANGE_parse_accounts (
wa->priority = priority;
if (NULL != conversion_url)
wa->conversion_url = GNUNET_strdup (conversion_url);
+ if (NULL != open_banking_gateway)
+ wa->open_banking_gateway = GNUNET_strdup (open_banking_gateway);
+ if (NULL != wire_transfer_gateway)
+ wa->wire_transfer_gateway = GNUNET_strdup (wire_transfer_gateway);
if (NULL != bank_label)
wa->bank_label = GNUNET_strdup (bank_label);
} /* end 'for all accounts */
@@ -636,6 +662,8 @@ TALER_EXCHANGE_free_accounts (
GNUNET_free (wa->fpayto_uri.full_payto);
GNUNET_free (wa->conversion_url);
+ GNUNET_free (wa->open_banking_gateway);
+ GNUNET_free (wa->wire_transfer_gateway);
GNUNET_free (wa->bank_label);
free_restrictions (wa->credit_restrictions_length,
wa->credit_restrictions);
diff --git a/src/lib/exchange_api_handle.c b/src/lib/exchange_api_handle.c
@@ -45,7 +45,7 @@
/**
* How many versions are we backwards compatible with?
*/
-#define EXCHANGE_PROTOCOL_AGE 7
+#define EXCHANGE_PROTOCOL_AGE 0
/**
* Set to 1 for extra debug logging.
@@ -929,8 +929,6 @@ TALER_EXCHANGE_decode_keys_json_ (
const json_t *fees;
const json_t *wads;
const char *shopping_url = NULL;
- const char *open_banking_gateway = NULL;
- const char *wire_transfer_gateway = NULL;
const char *bank_compliance_language = NULL;
struct SignatureContext sig_ctx = { 0 };
@@ -1049,14 +1047,6 @@ TALER_EXCHANGE_decode_keys_json_ (
&shopping_url),
NULL),
GNUNET_JSON_spec_mark_optional (
- GNUNET_JSON_spec_string ("open_banking_gateway",
- &open_banking_gateway),
- NULL),
- GNUNET_JSON_spec_mark_optional (
- GNUNET_JSON_spec_string ("wire_transfer_gateway",
- &wire_transfer_gateway),
- NULL),
- GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_string ("bank_compliance_language",
&bank_compliance_language),
NULL),
@@ -1158,10 +1148,6 @@ TALER_EXCHANGE_decode_keys_json_ (
key_data->asset_type = GNUNET_strdup (asset_type);
if (NULL != shopping_url)
key_data->shopping_url = GNUNET_strdup (shopping_url);
- if (NULL != open_banking_gateway)
- key_data->open_banking_gateway = GNUNET_strdup (open_banking_gateway);
- if (NULL != wire_transfer_gateway)
- key_data->wire_transfer_gateway = GNUNET_strdup (wire_transfer_gateway);
if (NULL != bank_compliance_language)
key_data->bank_compliance_language
= GNUNET_strdup (bank_compliance_language);
@@ -1714,8 +1700,6 @@ TALER_EXCHANGE_keys_decref (struct TALER_EXCHANGE_Keys *keys)
GNUNET_free (keys->currency);
GNUNET_free (keys->asset_type);
GNUNET_free (keys->shopping_url);
- GNUNET_free (keys->open_banking_gateway);
- GNUNET_free (keys->wire_transfer_gateway);
GNUNET_free (keys->bank_compliance_language);
for (unsigned int i = 0; i < keys->num_wad_partners; i++)
GNUNET_free (keys->wad_partners[i].partner_base_url);
@@ -2149,6 +2133,12 @@ TALER_EXCHANGE_keys_to_json (const struct TALER_EXCHANGE_Keys *kd)
GNUNET_JSON_pack_allow_null (
GNUNET_JSON_pack_string ("conversion_url",
acc->conversion_url)),
+ GNUNET_JSON_pack_allow_null (
+ GNUNET_JSON_pack_string ("open_banking_gateway",
+ acc->open_banking_gateway)),
+ GNUNET_JSON_pack_allow_null (
+ GNUNET_JSON_pack_string ("wire_transfer_gateway",
+ acc->wire_transfer_gateway)),
GNUNET_JSON_pack_int64 ("priority",
acc->priority),
GNUNET_JSON_pack_allow_null (
@@ -2324,12 +2314,6 @@ TALER_EXCHANGE_keys_to_json (const struct TALER_EXCHANGE_Keys *kd)
GNUNET_JSON_pack_string ("shopping_url",
kd->shopping_url)),
GNUNET_JSON_pack_allow_null (
- GNUNET_JSON_pack_string ("open_banking_gateway",
- kd->open_banking_gateway)),
- GNUNET_JSON_pack_allow_null (
- GNUNET_JSON_pack_string ("wire_transfer_gateway",
- kd->wire_transfer_gateway)),
- GNUNET_JSON_pack_allow_null (
GNUNET_JSON_pack_string ("bank_compliance_language",
kd->bank_compliance_language)),
GNUNET_JSON_pack_bool ("disable_direct_deposit",
diff --git a/src/lib/exchange_api_post-management-wire.c b/src/lib/exchange_api_post-management-wire.c
@@ -79,6 +79,16 @@ struct TALER_EXCHANGE_PostManagementWireHandle
char *conversion_url;
/**
+ * URL of the open banking gateway, or NULL.
+ */
+ char *open_banking_gateway;
+
+ /**
+ * URL of the wire transfer gateway, or NULL.
+ */
+ char *wire_transfer_gateway;
+
+ /**
* JSON encoding of debit restrictions (we hold a reference).
*/
json_t *debit_restrictions;
@@ -195,9 +205,6 @@ TALER_EXCHANGE_post_management_wire_create (
struct GNUNET_CURL_Context *ctx,
const char *url,
const struct TALER_FullPayto payto_uri,
- const char *conversion_url,
- const json_t *debit_restrictions,
- const json_t *credit_restrictions,
struct GNUNET_TIME_Timestamp validity_start,
const struct TALER_MasterSignatureP *master_sig1,
const struct TALER_MasterSignatureP *master_sig2)
@@ -218,11 +225,10 @@ TALER_EXCHANGE_post_management_wire_create (
pmwh->ctx = ctx;
pmwh->base_url = GNUNET_strdup (url);
pmwh->payto_uri_str = GNUNET_strdup (payto_uri.full_payto);
- pmwh->conversion_url = (NULL != conversion_url)
- ? GNUNET_strdup (conversion_url)
- : NULL;
- pmwh->debit_restrictions = json_incref ((json_t *) debit_restrictions);
- pmwh->credit_restrictions = json_incref ((json_t *) credit_restrictions);
+ pmwh->debit_restrictions = json_array ();
+ GNUNET_assert (NULL != pmwh->debit_restrictions);
+ pmwh->credit_restrictions = json_array ();
+ GNUNET_assert (NULL != pmwh->credit_restrictions);
pmwh->validity_start = validity_start;
pmwh->master_sig1 = *master_sig1;
pmwh->master_sig2 = *master_sig2;
@@ -254,6 +260,36 @@ TALER_EXCHANGE_post_management_wire_set_options_ (
case TALER_EXCHANGE_POST_MANAGEMENT_WIRE_OPTION_PRIORITY:
pmwh->priority = opt->details.priority;
break;
+ case TALER_EXCHANGE_POST_MANAGEMENT_WIRE_OPTION_CONVERSION_URL:
+ GNUNET_free (pmwh->conversion_url);
+ pmwh->conversion_url = (NULL != opt->details.conversion_url)
+ ? GNUNET_strdup (opt->details.conversion_url)
+ : NULL;
+ break;
+ case TALER_EXCHANGE_POST_MANAGEMENT_WIRE_OPTION_OPEN_BANKING_GATEWAY:
+ GNUNET_free (pmwh->open_banking_gateway);
+ pmwh->open_banking_gateway = (NULL != opt->details.open_banking_gateway)
+ ? GNUNET_strdup (opt->details.open_banking_gateway)
+ : NULL;
+ break;
+ case TALER_EXCHANGE_POST_MANAGEMENT_WIRE_OPTION_WIRE_TRANSFER_GATEWAY:
+ GNUNET_free (pmwh->wire_transfer_gateway);
+ pmwh->wire_transfer_gateway = (NULL != opt->details.wire_transfer_gateway)
+ ? GNUNET_strdup (opt->details.wire_transfer_gateway)
+ : NULL;
+ break;
+ case TALER_EXCHANGE_POST_MANAGEMENT_WIRE_OPTION_CREDIT_RESTRICTIONS:
+ json_decref (pmwh->credit_restrictions);
+ pmwh->credit_restrictions = (NULL != opt->details.credit_restrictions)
+ ? json_incref ((json_t *) opt->details.credit_restrictions)
+ : json_array ();
+ break;
+ case TALER_EXCHANGE_POST_MANAGEMENT_WIRE_OPTION_DEBIT_RESTRICTIONS:
+ json_decref (pmwh->debit_restrictions);
+ pmwh->debit_restrictions = (NULL != opt->details.debit_restrictions)
+ ? json_incref ((json_t *) opt->details.debit_restrictions)
+ : json_array ();
+ break;
default:
GNUNET_break (0);
return GNUNET_SYSERR;
@@ -297,6 +333,12 @@ TALER_EXCHANGE_post_management_wire_start (
GNUNET_JSON_pack_string ("conversion_url",
pmwh->conversion_url)),
GNUNET_JSON_pack_allow_null (
+ GNUNET_JSON_pack_string ("open_banking_gateway",
+ pmwh->open_banking_gateway)),
+ GNUNET_JSON_pack_allow_null (
+ GNUNET_JSON_pack_string ("wire_transfer_gateway",
+ pmwh->wire_transfer_gateway)),
+ GNUNET_JSON_pack_allow_null (
GNUNET_JSON_pack_string ("bank_label",
pmwh->bank_label)),
GNUNET_JSON_pack_int64 ("priority",
@@ -318,8 +360,6 @@ TALER_EXCHANGE_post_management_wire_start (
if (NULL != eh)
curl_easy_cleanup (eh);
json_decref (body);
- GNUNET_free (pmwh->url);
- pmwh->url = NULL;
return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE;
}
json_decref (body);
@@ -332,12 +372,7 @@ TALER_EXCHANGE_post_management_wire_start (
&handle_wire_finished,
pmwh);
if (NULL == pmwh->job)
- {
- TALER_curl_easy_post_finished (&pmwh->post_ctx);
- GNUNET_free (pmwh->url);
- pmwh->url = NULL;
return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE;
- }
return TALER_EC_NONE;
}
@@ -356,6 +391,8 @@ TALER_EXCHANGE_post_management_wire_cancel (
json_decref (pmwh->credit_restrictions);
GNUNET_free (pmwh->payto_uri_str);
GNUNET_free (pmwh->conversion_url);
+ GNUNET_free (pmwh->open_banking_gateway);
+ GNUNET_free (pmwh->wire_transfer_gateway);
GNUNET_free (pmwh->bank_label);
GNUNET_free (pmwh->url);
GNUNET_free (pmwh->base_url);
diff --git a/src/testing/test_exchange_api.conf b/src/testing/test_exchange_api.conf
@@ -53,6 +53,7 @@ HTTP_PORT = 8082
[exchange]
CURRENCY = EUR
CURRENCY_ROUND_UNIT = EUR:0.01
+TINY_AMOUNT = EUR:0.01
TERMS_ETAG = exchange-tos-tops-v0
PRIVACY_ETAG = 0
PORT = 8081
diff --git a/src/testing/testing_api_cmd_wire_add.c b/src/testing/testing_api_cmd_wire_add.c
@@ -155,6 +155,8 @@ wire_add_run (void *cls,
&master_priv));
TALER_exchange_offline_wire_add_sign (ds->payto_uri,
NULL,
+ NULL,
+ NULL,
debit_rest,
credit_rest,
now,
@@ -162,6 +164,8 @@ wire_add_run (void *cls,
&master_sig1);
TALER_exchange_wire_signature_make (ds->payto_uri,
NULL,
+ NULL,
+ NULL,
debit_rest,
credit_rest,
master_priv,
@@ -171,20 +175,24 @@ wire_add_run (void *cls,
TALER_TESTING_interpreter_get_context (is),
exchange_url,
ds->payto_uri,
- NULL,
- debit_rest,
- credit_rest,
now,
&master_sig1,
&master_sig2);
- json_decref (debit_rest);
- json_decref (credit_rest);
if (NULL == ds->dh)
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (is);
return;
}
+ TALER_EXCHANGE_post_management_wire_set_options (
+ ds->dh,
+ TALER_EXCHANGE_post_management_wire_option_bank_label ("test-account"),
+ TALER_EXCHANGE_post_management_wire_option_debit_restrictions (
+ debit_rest),
+ TALER_EXCHANGE_post_management_wire_option_credit_restrictions (
+ credit_rest));
+ json_decref (debit_rest);
+ json_decref (credit_rest);
TALER_EXCHANGE_post_management_wire_start (ds->dh, &wire_add_cb, ds);
}
diff --git a/src/util/offline_signatures.c b/src/util/offline_signatures.c
@@ -685,6 +685,18 @@ struct TALER_MasterAddWirePS
struct GNUNET_HashCode h_conversion_url;
/**
+ * Hash over the open banking gateway URL, all zeros if there
+ * is no open banking gateway URL.
+ */
+ struct GNUNET_HashCode h_open_banking_gateway;
+
+ /**
+ * Hash over the wire transfer gateway URL, all zeros if there
+ * is no wire transfer gateway URL.
+ */
+ struct GNUNET_HashCode h_wire_transfer_gateway;
+
+ /**
* Hash over the debit restrictions.
*/
struct GNUNET_HashCode h_debit_restrictions;
@@ -693,6 +705,51 @@ struct TALER_MasterAddWirePS
* Hash over the credit restrictions.
*/
struct GNUNET_HashCode h_credit_restrictions;
+
+};
+
+
+/**
+ * @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.
+ *
+ * Legacy pre-v33 protocol version.
+ */
+struct TALER_MasterAddWire32PS
+{
+
+ /**
+ * Purpose is #TALER_SIGNATURE_MASTER_ADD_WIRE. Signed
+ * by a `struct TALER_MasterPublicKeyP` using EdDSA.
+ */
+ struct GNUNET_CRYPTO_SignaturePurpose purpose;
+
+ /**
+ * Time of the change.
+ */
+ struct GNUNET_TIME_TimestampNBO start_date;
+
+ /**
+ * Hash over the exchange's payto URI.
+ */
+ struct TALER_FullPaytoHashP 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
@@ -702,6 +759,8 @@ void
TALER_exchange_offline_wire_add_sign (
const struct TALER_FullPayto payto_uri,
const char *conversion_url,
+ const char *open_banking_gateway,
+ const char *wire_transfer_gateway,
const json_t *debit_restrictions,
const json_t *credit_restrictions,
struct GNUNET_TIME_Timestamp now,
@@ -720,6 +779,14 @@ TALER_exchange_offline_wire_add_sign (
GNUNET_CRYPTO_hash (conversion_url,
strlen (conversion_url) + 1,
&kv.h_conversion_url);
+ if (NULL != open_banking_gateway)
+ GNUNET_CRYPTO_hash (open_banking_gateway,
+ strlen (open_banking_gateway) + 1,
+ &kv.h_open_banking_gateway);
+ if (NULL != wire_transfer_gateway)
+ GNUNET_CRYPTO_hash (wire_transfer_gateway,
+ strlen (wire_transfer_gateway) + 1,
+ &kv.h_wire_transfer_gateway);
TALER_json_hash (debit_restrictions,
&kv.h_debit_restrictions);
TALER_json_hash (credit_restrictions,
@@ -734,6 +801,8 @@ enum GNUNET_GenericReturnValue
TALER_exchange_offline_wire_add_verify (
const struct TALER_FullPayto payto_uri,
const char *conversion_url,
+ const char *open_banking_gateway,
+ const char *wire_transfer_gateway,
const json_t *debit_restrictions,
const json_t *credit_restrictions,
struct GNUNET_TIME_Timestamp sign_time,
@@ -752,6 +821,49 @@ TALER_exchange_offline_wire_add_verify (
GNUNET_CRYPTO_hash (conversion_url,
strlen (conversion_url) + 1,
&aw.h_conversion_url);
+ if (NULL != open_banking_gateway)
+ GNUNET_CRYPTO_hash (open_banking_gateway,
+ strlen (open_banking_gateway) + 1,
+ &aw.h_open_banking_gateway);
+ if (NULL != wire_transfer_gateway)
+ GNUNET_CRYPTO_hash (wire_transfer_gateway,
+ strlen (wire_transfer_gateway) + 1,
+ &aw.h_wire_transfer_gateway);
+ 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,
+ &aw,
+ &master_sig->eddsa_signature,
+ &master_pub->eddsa_pub);
+}
+
+
+enum GNUNET_GenericReturnValue
+TALER_exchange_offline_wire_add_verify_32 (
+ const struct TALER_FullPayto 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)
+{
+ struct TALER_MasterAddWire32PS aw = {
+ .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_ADD_WIRE),
+ .purpose.size = htonl (sizeof (aw)),
+ .start_date = GNUNET_TIME_timestamp_hton (sign_time),
+ };
+
+ TALER_full_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,
@@ -1140,6 +1252,53 @@ struct TALER_MasterWireDetailsPS
struct GNUNET_HashCode h_conversion_url;
/**
+ * Hash over the open banking gateway URL, all zeros if there
+ * is no open banking gateway URL.
+ */
+ struct GNUNET_HashCode h_open_banking_gateway;
+
+ /**
+ * Hash over the wire transfer gateway URL, all zeros if there
+ * is no wire transfer gateway URL.
+ */
+ struct GNUNET_HashCode h_wire_transfer_gateway;
+
+ /**
+ * Hash over the debit restrictions.
+ */
+ struct GNUNET_HashCode h_debit_restrictions;
+
+ /**
+ * Hash over the credit restrictions.
+ */
+ struct GNUNET_HashCode h_credit_restrictions;
+
+};
+
+/**
+ * @brief Information signed by the exchange's master
+ * key affirming the IBAN details for the exchange.
+ */
+struct TALER_MasterWireDetails32PS
+{
+
+ /**
+ * Purpose is #TALER_SIGNATURE_MASTER_WIRE_DETAILS.
+ */
+ struct GNUNET_CRYPTO_SignaturePurpose purpose;
+
+ /**
+ * Hash over the account holder's payto:// URL.
+ */
+ struct TALER_FullPaytoHashP 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;
@@ -1155,9 +1314,42 @@ GNUNET_NETWORK_STRUCT_END
enum GNUNET_GenericReturnValue
+TALER_exchange_wire_signature_check32 (
+ const struct TALER_FullPayto 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_MasterWireDetails32PS wd = {
+ .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_WIRE_DETAILS),
+ .purpose.size = htonl (sizeof (wd))
+ };
+
+ TALER_full_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);
+}
+
+
+enum GNUNET_GenericReturnValue
TALER_exchange_wire_signature_check (
const struct TALER_FullPayto payto_uri,
const char *conversion_url,
+ const char *open_banking_gateway,
+ const char *wire_transfer_gateway,
const json_t *debit_restrictions,
const json_t *credit_restrictions,
const struct TALER_MasterPublicKeyP *master_pub,
@@ -1174,6 +1366,14 @@ TALER_exchange_wire_signature_check (
GNUNET_CRYPTO_hash (conversion_url,
strlen (conversion_url) + 1,
&wd.h_conversion_url);
+ if (NULL != open_banking_gateway)
+ GNUNET_CRYPTO_hash (open_banking_gateway,
+ strlen (open_banking_gateway) + 1,
+ &wd.h_open_banking_gateway);
+ if (NULL != wire_transfer_gateway)
+ GNUNET_CRYPTO_hash (wire_transfer_gateway,
+ strlen (wire_transfer_gateway) + 1,
+ &wd.h_wire_transfer_gateway);
TALER_json_hash (debit_restrictions,
&wd.h_debit_restrictions);
TALER_json_hash (credit_restrictions,
@@ -1189,6 +1389,8 @@ void
TALER_exchange_wire_signature_make (
const struct TALER_FullPayto payto_uri,
const char *conversion_url,
+ const char *open_banking_gateway,
+ const char *wire_transfer_gateway,
const json_t *debit_restrictions,
const json_t *credit_restrictions,
const struct TALER_MasterPrivateKeyP *master_priv,
@@ -1205,6 +1407,14 @@ TALER_exchange_wire_signature_make (
GNUNET_CRYPTO_hash (conversion_url,
strlen (conversion_url) + 1,
&wd.h_conversion_url);
+ if (NULL != open_banking_gateway)
+ GNUNET_CRYPTO_hash (open_banking_gateway,
+ strlen (open_banking_gateway) + 1,
+ &wd.h_open_banking_gateway);
+ if (NULL != wire_transfer_gateway)
+ GNUNET_CRYPTO_hash (wire_transfer_gateway,
+ strlen (wire_transfer_gateway) + 1,
+ &wd.h_wire_transfer_gateway);
TALER_json_hash (debit_restrictions,
&wd.h_debit_restrictions);
TALER_json_hash (credit_restrictions,
diff --git a/src/util/test_crypto.c b/src/util/test_crypto.c
@@ -341,6 +341,8 @@ test_exchange_sigs (void)
GNUNET_assert (NULL != rest);
TALER_exchange_wire_signature_make (pt,
NULL,
+ "https://example.com/",
+ NULL,
rest,
rest,
&priv,
@@ -350,6 +352,8 @@ test_exchange_sigs (void)
if (GNUNET_OK !=
TALER_exchange_wire_signature_check (pt,
NULL,
+ "https://example.com/",
+ NULL,
rest,
rest,
&pub,
@@ -362,6 +366,8 @@ test_exchange_sigs (void)
TALER_exchange_wire_signature_check (
pto,
NULL,
+ "https://example.com/",
+ NULL,
rest,
rest,
&pub,
@@ -374,6 +380,8 @@ test_exchange_sigs (void)
TALER_exchange_wire_signature_check (
pt,
"http://example.com/",
+ NULL,
+ NULL,
rest,
rest,
&pub,