change taler-exchange-sepa to a more generic taler-exchange-wire tool using the wire plugins (#4237)
This commit is contained in:
parent
937078bbdc
commit
daae3d3ddf
@ -10,6 +10,7 @@ man_MANS = \
|
|||||||
taler-exchange-keyup.1 \
|
taler-exchange-keyup.1 \
|
||||||
taler-exchange-keycheck.1 \
|
taler-exchange-keycheck.1 \
|
||||||
taler-exchange-reservemod.1 \
|
taler-exchange-reservemod.1 \
|
||||||
|
taler-exchange-wire.1 \
|
||||||
taler.conf.5
|
taler.conf.5
|
||||||
|
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
|
@ -1,41 +0,0 @@
|
|||||||
.TH TALER\-EXCHANGE\-SEPA 1 "Apr 22, 2015" "GNU Taler"
|
|
||||||
|
|
||||||
.SH NAME
|
|
||||||
taler\-exchange\-sepa \- Create the master-key signed response to /wire/sepa.
|
|
||||||
|
|
||||||
.SH SYNOPSIS
|
|
||||||
.B taler\-exchange\-sepa
|
|
||||||
.RI [ options ]
|
|
||||||
.br
|
|
||||||
|
|
||||||
.SH DESCRIPTION
|
|
||||||
\fBtaler\-exchange\-sepa\fP is used to create the exchange's reply to a /wire/sepa request. It converts the bank details into the appropriate signed response. This needs to be done using the long-term offline master key.
|
|
||||||
|
|
||||||
.SH OPTIONS
|
|
||||||
.B
|
|
||||||
.IP "\-b BIC, \-\-bic=BIC"
|
|
||||||
Specifies the BIC code to use.
|
|
||||||
.B
|
|
||||||
.IP "\-i IBAN, \-\-iban=IBAN"
|
|
||||||
Specifies the IBAN to use.
|
|
||||||
.B
|
|
||||||
.IP "\-n NAME, \-\-name=NAME"
|
|
||||||
Specifies the name of the account holder.
|
|
||||||
.B
|
|
||||||
.IP "\-m MASTERKEYFILE, \-\-master=MASTERKEYFILE"
|
|
||||||
Specifies the name of the file containing the exchange's master key.
|
|
||||||
.B
|
|
||||||
.IP "\-o FILENAME, \-\-output=FILENAME"
|
|
||||||
Where to write the SEPA_RESPONSE_FILE.
|
|
||||||
.B
|
|
||||||
.IP "\-h, \-\-help"
|
|
||||||
Print short help on options.
|
|
||||||
.B
|
|
||||||
.IP "\-v, \-\-version"
|
|
||||||
Print version information.
|
|
||||||
|
|
||||||
.SH BUGS
|
|
||||||
Report bugs by using Mantis <https://gnunet.org/bugs/> or by sending electronic mail to <taler@gnu.org>
|
|
||||||
|
|
||||||
.SH "SEE ALSO"
|
|
||||||
\fBtaler\-exchange\-httpd\fP(1), \fBtaler.conf\fP(5)
|
|
38
doc/taler-exchange-wire.1
Normal file
38
doc/taler-exchange-wire.1
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
.TH TALER\-EXCHANGE\-WIRE 1 "Apr 2, 2016" "GNU Taler"
|
||||||
|
|
||||||
|
.SH NAME
|
||||||
|
taler\-exchange\-wire \- Create the master-key signed responses to /wire.
|
||||||
|
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B taler\-exchange\-wire
|
||||||
|
.RI [ options ]
|
||||||
|
.br
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fBtaler\-exchange\-wire\fP is used to create the exchange's reply to a /wire request. It converts the bank details into the appropriate signed response. This needs to be done using the long-term offline master key.
|
||||||
|
|
||||||
|
.SH OPTIONS
|
||||||
|
.B
|
||||||
|
.IP "\-j JSON, \-\-json=JSON"
|
||||||
|
Gives JSON with all of the relevant account details in a method-specific format.
|
||||||
|
.B
|
||||||
|
.IP "\-t METHOD, \-\-type=METHOD"
|
||||||
|
Specifies the wire transfer method to use. Common are 'test' and 'sepa'.
|
||||||
|
.B
|
||||||
|
.IP "\-m MASTERKEYFILE, \-\-master=MASTERKEYFILE"
|
||||||
|
Specifies the name of the file containing the exchange's master key.
|
||||||
|
.B
|
||||||
|
.IP "\-o FILENAME, \-\-output=FILENAME"
|
||||||
|
Where to write the SEPA_RESPONSE_FILE.
|
||||||
|
.B
|
||||||
|
.IP "\-h, \-\-help"
|
||||||
|
Print short help on options.
|
||||||
|
.B
|
||||||
|
.IP "\-v, \-\-version"
|
||||||
|
Print version information.
|
||||||
|
|
||||||
|
.SH BUGS
|
||||||
|
Report bugs by using Mantis <https://gnunet.org/bugs/> or by sending electronic mail to <taler@gnu.org>
|
||||||
|
|
||||||
|
.SH "SEE ALSO"
|
||||||
|
\fBtaler\-exchange\-httpd\fP(1), \fBtaler.conf\fP(5)
|
@ -11,7 +11,7 @@ bin_PROGRAMS = \
|
|||||||
taler-exchange-keyup \
|
taler-exchange-keyup \
|
||||||
taler-exchange-keycheck \
|
taler-exchange-keycheck \
|
||||||
taler-exchange-reservemod \
|
taler-exchange-reservemod \
|
||||||
taler-exchange-sepa \
|
taler-exchange-wire \
|
||||||
taler-exchange-dbinit
|
taler-exchange-dbinit
|
||||||
|
|
||||||
taler_exchange_keyup_SOURCES = \
|
taler_exchange_keyup_SOURCES = \
|
||||||
@ -33,15 +33,15 @@ taler_auditor_sign_LDADD = \
|
|||||||
-lgnunetutil $(XLIB)
|
-lgnunetutil $(XLIB)
|
||||||
|
|
||||||
|
|
||||||
taler_exchange_sepa_SOURCES = \
|
taler_exchange_wire_SOURCES = \
|
||||||
taler-exchange-sepa.c
|
taler-exchange-wire.c
|
||||||
taler_exchange_sepa_LDADD = \
|
taler_exchange_wire_LDADD = \
|
||||||
$(LIBGCRYPT_LIBS) \
|
$(LIBGCRYPT_LIBS) \
|
||||||
$(top_builddir)/src/util/libtalerutil.la \
|
$(top_builddir)/src/util/libtalerutil.la \
|
||||||
-lgnunetjson \
|
-lgnunetjson \
|
||||||
-lgnunetutil \
|
-lgnunetutil \
|
||||||
-ljansson $(XLIB)
|
-ljansson $(XLIB)
|
||||||
taler_exchange_sepa_LDFLAGS = $(POSTGRESQL_LDFLAGS)
|
taler_exchange_wire_LDFLAGS = $(POSTGRESQL_LDFLAGS)
|
||||||
|
|
||||||
taler_exchange_keycheck_SOURCES = \
|
taler_exchange_keycheck_SOURCES = \
|
||||||
taler-exchange-keycheck.c
|
taler-exchange-keycheck.c
|
||||||
|
@ -1,189 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is part of TALER
|
|
||||||
Copyright (C) 2015 GNUnet e.V.
|
|
||||||
|
|
||||||
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, If not, see <http://www.gnu.org/licenses/>
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @file taler-exchange-sepa.c
|
|
||||||
* @brief Create signed response for /wire/sepa requests.
|
|
||||||
* @author Christian Grothoff
|
|
||||||
*/
|
|
||||||
#include <platform.h>
|
|
||||||
#include <jansson.h>
|
|
||||||
#include <gnunet/gnunet_json_lib.h>
|
|
||||||
#include "taler_crypto_lib.h"
|
|
||||||
#include "taler_signatures.h"
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Filename of the master private key.
|
|
||||||
*/
|
|
||||||
static char *masterkeyfile;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Account holder name.
|
|
||||||
*/
|
|
||||||
static char *sepa_name;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Account holder address.
|
|
||||||
*/
|
|
||||||
static char *sepa_address;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* IBAN number.
|
|
||||||
*/
|
|
||||||
static char *iban;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* BIC number.
|
|
||||||
*/
|
|
||||||
static char *bic;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Where to write the result.
|
|
||||||
*/
|
|
||||||
static char *output_filename;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The main function of the taler-exchange-sepa tool. This tool is used
|
|
||||||
* to sign the SEPA bank account details using the master key.
|
|
||||||
*
|
|
||||||
* @param argc number of arguments from the command line
|
|
||||||
* @param argv command line arguments
|
|
||||||
* @return 0 ok, 1 on error
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
main (int argc,
|
|
||||||
char *const *argv)
|
|
||||||
{
|
|
||||||
static const struct GNUNET_GETOPT_CommandLineOption options[] = {
|
|
||||||
{'a', "address", "ADDRESS",
|
|
||||||
"account holder address", 1,
|
|
||||||
&GNUNET_GETOPT_set_string, &sepa_address},
|
|
||||||
{'b', "bic", "BICCODE",
|
|
||||||
"bank BIC code", 1,
|
|
||||||
&GNUNET_GETOPT_set_string, &bic},
|
|
||||||
{'i', "iban", "IBAN",
|
|
||||||
"IBAN number of the account", 1,
|
|
||||||
&GNUNET_GETOPT_set_string, &iban},
|
|
||||||
{'m', "master-key", "FILE",
|
|
||||||
"master key file (private key)", 1,
|
|
||||||
&GNUNET_GETOPT_set_filename, &masterkeyfile},
|
|
||||||
{'n', "name", "NAME",
|
|
||||||
"name of the account holder", 1,
|
|
||||||
&GNUNET_GETOPT_set_string, &sepa_name},
|
|
||||||
{'o', "output", "FILE",
|
|
||||||
"where to write the result", 1,
|
|
||||||
&GNUNET_GETOPT_set_filename, &output_filename},
|
|
||||||
TALER_GETOPT_OPTION_HELP ("Setup /wire/sepa response"),
|
|
||||||
GNUNET_GETOPT_OPTION_VERSION (VERSION "-" VCS_VERSION),
|
|
||||||
GNUNET_GETOPT_OPTION_END
|
|
||||||
};
|
|
||||||
struct GNUNET_CRYPTO_EddsaPrivateKey *eddsa_priv;
|
|
||||||
struct TALER_MasterWireSepaDetailsPS wsd;
|
|
||||||
struct TALER_MasterSignatureP sig;
|
|
||||||
struct GNUNET_HashContext *hc;
|
|
||||||
json_t *reply;
|
|
||||||
char *json_str;
|
|
||||||
struct GNUNET_HashCode salt;
|
|
||||||
|
|
||||||
GNUNET_assert (GNUNET_OK ==
|
|
||||||
GNUNET_log_setup ("taler-exchange-sepa",
|
|
||||||
"WARNING",
|
|
||||||
NULL));
|
|
||||||
|
|
||||||
if (GNUNET_GETOPT_run ("taler-exchange-sepa",
|
|
||||||
options,
|
|
||||||
argc, argv) < 0)
|
|
||||||
return 1;
|
|
||||||
if (NULL == masterkeyfile)
|
|
||||||
{
|
|
||||||
fprintf (stderr,
|
|
||||||
"Master key file not given\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
eddsa_priv = GNUNET_CRYPTO_eddsa_key_create_from_file (masterkeyfile);
|
|
||||||
if (NULL == eddsa_priv)
|
|
||||||
{
|
|
||||||
fprintf (stderr,
|
|
||||||
"Failed to initialize master key from file `%s'\n",
|
|
||||||
masterkeyfile);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if ( (NULL == sepa_address) ||
|
|
||||||
(NULL == iban) ||
|
|
||||||
(NULL == sepa_name) ||
|
|
||||||
(NULL == bic) )
|
|
||||||
{
|
|
||||||
fprintf (stderr,
|
|
||||||
"Required arguments missing\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compute message to sign */
|
|
||||||
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
|
|
||||||
&salt,
|
|
||||||
sizeof (salt));
|
|
||||||
hc = GNUNET_CRYPTO_hash_context_start ();
|
|
||||||
GNUNET_CRYPTO_hash_context_read (hc,
|
|
||||||
sepa_name,
|
|
||||||
strlen (sepa_name) + 1);
|
|
||||||
GNUNET_CRYPTO_hash_context_read (hc,
|
|
||||||
iban,
|
|
||||||
strlen (iban) + 1);
|
|
||||||
GNUNET_CRYPTO_hash_context_read (hc,
|
|
||||||
bic,
|
|
||||||
strlen (bic) + 1);
|
|
||||||
wsd.purpose.size = htonl (sizeof (wsd));
|
|
||||||
wsd.purpose.purpose = htonl (TALER_SIGNATURE_MASTER_SEPA_DETAILS);
|
|
||||||
GNUNET_CRYPTO_hash_context_finish (hc,
|
|
||||||
&wsd.h_sepa_details);
|
|
||||||
GNUNET_CRYPTO_eddsa_sign (eddsa_priv,
|
|
||||||
&wsd.purpose,
|
|
||||||
&sig.eddsa_signature);
|
|
||||||
GNUNET_free (eddsa_priv);
|
|
||||||
|
|
||||||
/* build JSON message */
|
|
||||||
reply = json_pack ("{s:s, s:s, s:s, s:s, s:s, s:o, s:o}",
|
|
||||||
"type", "sepa",
|
|
||||||
"address", sepa_address,
|
|
||||||
"receiver_name", sepa_name,
|
|
||||||
"iban", iban,
|
|
||||||
"bic", bic,
|
|
||||||
"salt", GNUNET_JSON_from_data (&salt,
|
|
||||||
sizeof (salt)),
|
|
||||||
"sig", GNUNET_JSON_from_data (&sig,
|
|
||||||
sizeof (sig)));
|
|
||||||
GNUNET_assert (NULL != reply);
|
|
||||||
|
|
||||||
/* dump result to stdout */
|
|
||||||
json_str = json_dumps (reply, JSON_INDENT(2));
|
|
||||||
GNUNET_assert (NULL != json_str);
|
|
||||||
|
|
||||||
if (NULL != output_filename)
|
|
||||||
{
|
|
||||||
fclose (stdout);
|
|
||||||
stdout = fopen (output_filename,
|
|
||||||
"w+");
|
|
||||||
}
|
|
||||||
fprintf (stdout,
|
|
||||||
"%s",
|
|
||||||
json_str);
|
|
||||||
fflush (stdout);
|
|
||||||
free (json_str);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* end of taler-exchange-sepa.c */
|
|
201
src/exchange-tools/taler-exchange-wire.c
Normal file
201
src/exchange-tools/taler-exchange-wire.c
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
/*
|
||||||
|
This file is part of TALER
|
||||||
|
Copyright (C) 2015, 2016 Inria
|
||||||
|
|
||||||
|
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, If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @file taler-exchange-wire.c
|
||||||
|
* @brief Create signed response for /wire requests.
|
||||||
|
* @author Christian Grothoff
|
||||||
|
*/
|
||||||
|
#include <platform.h>
|
||||||
|
#include <jansson.h>
|
||||||
|
#include <gnunet/gnunet_json_lib.h>
|
||||||
|
#include "taler_crypto_lib.h"
|
||||||
|
#include "taler_wire_plugin.h"
|
||||||
|
#include "taler_signatures.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filename of the master private key.
|
||||||
|
*/
|
||||||
|
static char *masterkeyfile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Account holder information in JSON format.
|
||||||
|
*/
|
||||||
|
static char *json_in;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Which wire method is this for?
|
||||||
|
*/
|
||||||
|
static char *method;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Where to write the result.
|
||||||
|
*/
|
||||||
|
static char *output_filename;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The main function of the taler-exchange-sepa tool. This tool is used
|
||||||
|
* to sign the SEPA bank account details using the master key.
|
||||||
|
*
|
||||||
|
* @param argc number of arguments from the command line
|
||||||
|
* @param argv command line arguments
|
||||||
|
* @return 0 ok, 1 on error
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
main (int argc,
|
||||||
|
char *const *argv)
|
||||||
|
{
|
||||||
|
static const struct GNUNET_GETOPT_CommandLineOption options[] = {
|
||||||
|
{'j', "json", "JSON",
|
||||||
|
"account information in JSON format", 1,
|
||||||
|
&GNUNET_GETOPT_set_string, &json_in},
|
||||||
|
{'m', "master-key", "FILE",
|
||||||
|
"master key file (private key)", 1,
|
||||||
|
&GNUNET_GETOPT_set_filename, &masterkeyfile},
|
||||||
|
{'t', "type", "METHOD",
|
||||||
|
"which wire transfer method (i.e. 'test' or 'sepa') is this for?", 1,
|
||||||
|
&GNUNET_GETOPT_set_filename, &method},
|
||||||
|
{'o', "output", "FILE",
|
||||||
|
"where to write the result", 1,
|
||||||
|
&GNUNET_GETOPT_set_filename, &output_filename},
|
||||||
|
TALER_GETOPT_OPTION_HELP ("Setup /wire response"),
|
||||||
|
GNUNET_GETOPT_OPTION_VERSION (VERSION "-" VCS_VERSION),
|
||||||
|
GNUNET_GETOPT_OPTION_END
|
||||||
|
};
|
||||||
|
struct GNUNET_CRYPTO_EddsaPrivateKey *eddsa_priv;
|
||||||
|
struct TALER_MasterPrivateKeyP key;
|
||||||
|
struct TALER_MasterSignatureP sig;
|
||||||
|
json_t *j;
|
||||||
|
json_error_t err;
|
||||||
|
char *json_out;
|
||||||
|
struct GNUNET_HashCode salt;
|
||||||
|
char *lib_name;
|
||||||
|
struct TALER_WIRE_Plugin *plugin;
|
||||||
|
|
||||||
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
GNUNET_log_setup ("taler-exchange-wire",
|
||||||
|
"WARNING",
|
||||||
|
NULL));
|
||||||
|
|
||||||
|
if (GNUNET_GETOPT_run ("taler-exchange-wire",
|
||||||
|
options,
|
||||||
|
argc, argv) < 0)
|
||||||
|
return 1;
|
||||||
|
if (NULL == masterkeyfile)
|
||||||
|
{
|
||||||
|
fprintf (stderr,
|
||||||
|
"Master key file not given\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
eddsa_priv = GNUNET_CRYPTO_eddsa_key_create_from_file (masterkeyfile);
|
||||||
|
if (NULL == eddsa_priv)
|
||||||
|
{
|
||||||
|
fprintf (stderr,
|
||||||
|
"Failed to initialize master key from file `%s'\n",
|
||||||
|
masterkeyfile);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (NULL == json_in)
|
||||||
|
{
|
||||||
|
fprintf (stderr,
|
||||||
|
"Required -j argument missing\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (NULL == method)
|
||||||
|
{
|
||||||
|
fprintf (stderr,
|
||||||
|
"Required -t argument missing\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
j = json_loads (json_in,
|
||||||
|
JSON_REJECT_DUPLICATES,
|
||||||
|
&err);
|
||||||
|
if (NULL == j)
|
||||||
|
{
|
||||||
|
fprintf (stderr,
|
||||||
|
"Failed to parse JSON: %s (at offset %u)\n",
|
||||||
|
err.text,
|
||||||
|
(unsigned int) err.position);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
key.eddsa_priv = *eddsa_priv;
|
||||||
|
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
|
||||||
|
&salt,
|
||||||
|
sizeof (salt));
|
||||||
|
(void) GNUNET_asprintf (&lib_name,
|
||||||
|
"libtaler_plugin_wire_%s",
|
||||||
|
method);
|
||||||
|
plugin = GNUNET_PLUGIN_load (lib_name,
|
||||||
|
NULL);
|
||||||
|
if (NULL == plugin)
|
||||||
|
{
|
||||||
|
GNUNET_free (lib_name);
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Wire transfer method `%s' not supported\n",
|
||||||
|
method);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
plugin->library_name = lib_name;
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
plugin->sign_wire_details (plugin->cls,
|
||||||
|
j,
|
||||||
|
&key,
|
||||||
|
&salt,
|
||||||
|
&sig))
|
||||||
|
{
|
||||||
|
/* sign function should have logged applicable errors */
|
||||||
|
json_decref (j);
|
||||||
|
GNUNET_PLUGIN_unload (lib_name,
|
||||||
|
plugin);
|
||||||
|
GNUNET_free (lib_name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
GNUNET_PLUGIN_unload (lib_name,
|
||||||
|
plugin);
|
||||||
|
GNUNET_free (lib_name);
|
||||||
|
GNUNET_free (eddsa_priv);
|
||||||
|
|
||||||
|
/* add signature and salt to JSON message */
|
||||||
|
json_object_set_new (j,
|
||||||
|
"salt",
|
||||||
|
GNUNET_JSON_from_data (&salt,
|
||||||
|
sizeof (salt)));
|
||||||
|
json_object_set_new (j,
|
||||||
|
"sig",
|
||||||
|
GNUNET_JSON_from_data (&sig,
|
||||||
|
sizeof (sig)));
|
||||||
|
|
||||||
|
/* dump result to stdout */
|
||||||
|
json_out = json_dumps (j, JSON_INDENT(2));
|
||||||
|
json_decref (j);
|
||||||
|
GNUNET_assert (NULL != json_out);
|
||||||
|
|
||||||
|
if (NULL != output_filename)
|
||||||
|
{
|
||||||
|
fclose (stdout);
|
||||||
|
stdout = fopen (output_filename,
|
||||||
|
"w+");
|
||||||
|
}
|
||||||
|
fprintf (stdout,
|
||||||
|
"%s",
|
||||||
|
json_out);
|
||||||
|
fflush (stdout);
|
||||||
|
free (json_out);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* end of taler-exchange-wire.c */
|
@ -69,10 +69,16 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Signature where the Exchange confirms its SEPA details in
|
* Signature where the Exchange confirms its SEPA details in
|
||||||
* the /wire/sepa response.
|
* the /wire response.
|
||||||
*/
|
*/
|
||||||
#define TALER_SIGNATURE_MASTER_SEPA_DETAILS 1026
|
#define TALER_SIGNATURE_MASTER_SEPA_DETAILS 1026
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signature where the Exchange confirms its TEST details in
|
||||||
|
* the /wire response.
|
||||||
|
*/
|
||||||
|
#define TALER_SIGNATURE_MASTER_TEST_DETAILS 1027
|
||||||
|
|
||||||
|
|
||||||
/*********************************************/
|
/*********************************************/
|
||||||
/* Exchange online signatures (with signing key) */
|
/* Exchange online signatures (with signing key) */
|
||||||
@ -762,11 +768,12 @@ struct TALER_RefreshCommitLinkP
|
|||||||
* @brief Information signed by the exchange's master
|
* @brief Information signed by the exchange's master
|
||||||
* key affirming the SEPA details for the exchange.
|
* key affirming the SEPA details for the exchange.
|
||||||
*/
|
*/
|
||||||
struct TALER_MasterWireSepaDetailsPS
|
struct TALER_MasterWireDetailsPS
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Purpose is #TALER_SIGNATURE_MASTER_SEPA_DETAILS.
|
* Purpose is #TALER_SIGNATURE_MASTER_SEPA_DETAILS or
|
||||||
|
* #TALER_SIGNATURE_MASTER_TEST_DETAILS.
|
||||||
*/
|
*/
|
||||||
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
|
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
|
||||||
|
|
||||||
|
@ -113,6 +113,24 @@ struct TALER_WIRE_Plugin
|
|||||||
const char *account_name);
|
const char *account_name);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sign wire transfer details in the plugin-specific format.
|
||||||
|
*
|
||||||
|
* @param cls closure
|
||||||
|
* @param in wire transfer details in JSON format
|
||||||
|
* @param key private signing key to use
|
||||||
|
* @param salt salt to add
|
||||||
|
* @param[out] sig where to write the signature
|
||||||
|
* @return #GNUNET_OK on success
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
(*sign_wire_details)(void *cls,
|
||||||
|
const json_t *in,
|
||||||
|
const struct TALER_MasterPrivateKeyP *key,
|
||||||
|
const struct GNUNET_HashCode *salt,
|
||||||
|
struct TALER_MasterSignatureP *sig);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the given wire format JSON object is correctly formatted
|
* Check if the given wire format JSON object is correctly formatted
|
||||||
*
|
*
|
||||||
|
@ -351,6 +351,42 @@ validate_iban (const char *iban)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute purpose for signing.
|
||||||
|
*
|
||||||
|
* @param sepa_name name of the account holder
|
||||||
|
* @param iban bank account number in IBAN format
|
||||||
|
* @param bic bank identifier
|
||||||
|
* @param[out] mp purpose to be signed
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
compute_purpose (const char *sepa_name,
|
||||||
|
const char *iban,
|
||||||
|
const char *bic,
|
||||||
|
struct TALER_MasterWireDetailsPS *wsd)
|
||||||
|
{
|
||||||
|
struct GNUNET_HashContext *hc;
|
||||||
|
|
||||||
|
wsd->purpose.size = htonl (sizeof (struct TALER_MasterWireDetailsPS));
|
||||||
|
wsd->purpose.purpose = htonl (TALER_SIGNATURE_MASTER_SEPA_DETAILS);
|
||||||
|
hc = GNUNET_CRYPTO_hash_context_start ();
|
||||||
|
GNUNET_CRYPTO_hash_context_read (hc,
|
||||||
|
"sepa",
|
||||||
|
strlen ("sepa") + 1);
|
||||||
|
GNUNET_CRYPTO_hash_context_read (hc,
|
||||||
|
sepa_name,
|
||||||
|
strlen (sepa_name) + 1);
|
||||||
|
GNUNET_CRYPTO_hash_context_read (hc,
|
||||||
|
iban,
|
||||||
|
strlen (iban) + 1);
|
||||||
|
GNUNET_CRYPTO_hash_context_read (hc,
|
||||||
|
bic,
|
||||||
|
strlen (bic) + 1);
|
||||||
|
GNUNET_CRYPTO_hash_context_finish (hc,
|
||||||
|
&wsd->h_sepa_details);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify that the signature in the @a json for /wire/sepa is valid.
|
* Verify that the signature in the @a json for /wire/sepa is valid.
|
||||||
*
|
*
|
||||||
@ -365,14 +401,13 @@ verify_wire_sepa_signature_ok (const json_t *json,
|
|||||||
const struct TALER_MasterPublicKeyP *master_pub)
|
const struct TALER_MasterPublicKeyP *master_pub)
|
||||||
{
|
{
|
||||||
struct TALER_MasterSignatureP exchange_sig;
|
struct TALER_MasterSignatureP exchange_sig;
|
||||||
struct TALER_MasterWireSepaDetailsPS mp;
|
struct TALER_MasterWireDetailsPS mp;
|
||||||
const char *receiver_name;
|
const char *name;
|
||||||
const char *iban;
|
const char *iban;
|
||||||
const char *bic;
|
const char *bic;
|
||||||
struct GNUNET_HashContext *hc;
|
|
||||||
struct GNUNET_JSON_Specification spec[] = {
|
struct GNUNET_JSON_Specification spec[] = {
|
||||||
GNUNET_JSON_spec_fixed_auto ("sig", &exchange_sig),
|
GNUNET_JSON_spec_fixed_auto ("sig", &exchange_sig),
|
||||||
GNUNET_JSON_spec_string ("receiver_name", &receiver_name),
|
GNUNET_JSON_spec_string ("name", &name),
|
||||||
GNUNET_JSON_spec_string ("iban", &iban),
|
GNUNET_JSON_spec_string ("iban", &iban),
|
||||||
GNUNET_JSON_spec_string ("bic", &bic),
|
GNUNET_JSON_spec_string ("bic", &bic),
|
||||||
GNUNET_JSON_spec_end()
|
GNUNET_JSON_spec_end()
|
||||||
@ -391,22 +426,10 @@ verify_wire_sepa_signature_ok (const json_t *json,
|
|||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
|
compute_purpose (name,
|
||||||
mp.purpose.purpose = htonl (TALER_SIGNATURE_MASTER_SEPA_DETAILS);
|
iban,
|
||||||
mp.purpose.size = htonl (sizeof (struct TALER_MasterWireSepaDetailsPS));
|
bic,
|
||||||
hc = GNUNET_CRYPTO_hash_context_start ();
|
&mp);
|
||||||
GNUNET_CRYPTO_hash_context_read (hc,
|
|
||||||
receiver_name,
|
|
||||||
strlen (receiver_name) + 1);
|
|
||||||
GNUNET_CRYPTO_hash_context_read (hc,
|
|
||||||
iban,
|
|
||||||
strlen (iban) + 1);
|
|
||||||
GNUNET_CRYPTO_hash_context_read (hc,
|
|
||||||
bic,
|
|
||||||
strlen (bic) + 1);
|
|
||||||
GNUNET_CRYPTO_hash_context_finish (hc,
|
|
||||||
&mp.h_sepa_details);
|
|
||||||
|
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_SEPA_DETAILS,
|
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_SEPA_DETAILS,
|
||||||
&mp.purpose,
|
&mp.purpose,
|
||||||
@ -447,12 +470,12 @@ sepa_wire_validate (void *cls,
|
|||||||
"{"
|
"{"
|
||||||
"s:s," /* type: sepa */
|
"s:s," /* type: sepa */
|
||||||
"s:s," /* iban: IBAN */
|
"s:s," /* iban: IBAN */
|
||||||
"s:s," /* receiver_name: beneficiary name */
|
"s:s," /* name: beneficiary name */
|
||||||
"s:s" /* bic: beneficiary bank's BIC */
|
"s:s" /* bic: beneficiary bank's BIC */
|
||||||
"}",
|
"}",
|
||||||
"type", &type,
|
"type", &type,
|
||||||
"iban", &iban,
|
"iban", &iban,
|
||||||
"receiver_name", &name,
|
"name", &name,
|
||||||
"bic", &bic))
|
"bic", &bic))
|
||||||
{
|
{
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||||
@ -548,6 +571,70 @@ sepa_get_wire_details (void *cls,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sign wire transfer details in the plugin-specific format.
|
||||||
|
*
|
||||||
|
* @param cls closure
|
||||||
|
* @param in wire transfer details in JSON format
|
||||||
|
* @param key private signing key to use
|
||||||
|
* @param salt salt to add
|
||||||
|
* @param[out] sig where to write the signature
|
||||||
|
* @return #GNUNET_OK on success
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
sepa_sign_wire_details (void *cls,
|
||||||
|
const json_t *in,
|
||||||
|
const struct TALER_MasterPrivateKeyP *key,
|
||||||
|
const struct GNUNET_HashCode *salt,
|
||||||
|
struct TALER_MasterSignatureP *sig)
|
||||||
|
{
|
||||||
|
struct TALER_MasterWireDetailsPS wsd;
|
||||||
|
const char *sepa_name;
|
||||||
|
const char *iban;
|
||||||
|
const char *bic;
|
||||||
|
const char *type;
|
||||||
|
json_error_t err;
|
||||||
|
|
||||||
|
if (0 !=
|
||||||
|
json_unpack_ex ((json_t *) in,
|
||||||
|
&err,
|
||||||
|
0 /* flags */,
|
||||||
|
"{s:s, s:s, s:s, s:s}",
|
||||||
|
"type", &type,
|
||||||
|
"name", &sepa_name,
|
||||||
|
"iban", &iban,
|
||||||
|
"bic", &bic))
|
||||||
|
{
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||||
|
"Failed to unpack JSON: %s (at %u)\n",
|
||||||
|
err.text,
|
||||||
|
err.position);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
if (0 != strcmp (type,
|
||||||
|
"sepa"))
|
||||||
|
{
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||||
|
"`type' must be `sepa' for SEPA wire details\n");
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
if (1 != validate_iban (iban))
|
||||||
|
{
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||||
|
"IBAN invalid in SEPA wire details\n");
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
compute_purpose (sepa_name,
|
||||||
|
iban,
|
||||||
|
bic,
|
||||||
|
&wsd);
|
||||||
|
GNUNET_CRYPTO_eddsa_sign (&key->eddsa_priv,
|
||||||
|
&wsd.purpose,
|
||||||
|
&sig->eddsa_signature);
|
||||||
|
return GNUNET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare for exeuction of a wire transfer.
|
* Prepare for exeuction of a wire transfer.
|
||||||
*
|
*
|
||||||
@ -662,6 +749,7 @@ libtaler_plugin_wire_sepa_init (void *cls)
|
|||||||
plugin->cls = sc;
|
plugin->cls = sc;
|
||||||
plugin->amount_round = &sepa_amount_round;
|
plugin->amount_round = &sepa_amount_round;
|
||||||
plugin->get_wire_details = &sepa_get_wire_details;
|
plugin->get_wire_details = &sepa_get_wire_details;
|
||||||
|
plugin->sign_wire_details = &sepa_sign_wire_details;
|
||||||
plugin->wire_validate = &sepa_wire_validate;
|
plugin->wire_validate = &sepa_wire_validate;
|
||||||
plugin->prepare_wire_transfer = &sepa_prepare_wire_transfer;
|
plugin->prepare_wire_transfer = &sepa_prepare_wire_transfer;
|
||||||
plugin->prepare_wire_transfer_cancel = &sepa_prepare_wire_transfer_cancel;
|
plugin->prepare_wire_transfer_cancel = &sepa_prepare_wire_transfer_cancel;
|
||||||
|
@ -171,6 +171,28 @@ template_execute_wire_transfer (void *cls,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sign wire transfer details in the plugin-specific format.
|
||||||
|
*
|
||||||
|
* @param cls closure
|
||||||
|
* @param in wire transfer details in JSON format
|
||||||
|
* @param key private signing key to use
|
||||||
|
* @param salt salt to add
|
||||||
|
* @param[out] sig where to write the signature
|
||||||
|
* @return #GNUNET_OK on success
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
template_sign_wire_details (void *cls,
|
||||||
|
const json_t *in,
|
||||||
|
const struct TALER_MasterPrivateKeyP *key,
|
||||||
|
const struct GNUNET_HashCode *salt,
|
||||||
|
struct TALER_MasterSignatureP *sig)
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abort execution of a wire transfer. For example, because we are
|
* Abort execution of a wire transfer. For example, because we are
|
||||||
* shutting down. Note that if an execution is aborted, it may or
|
* shutting down. Note that if an execution is aborted, it may or
|
||||||
@ -236,6 +258,7 @@ libtaler_plugin_wire_template_init (void *cls)
|
|||||||
plugin->cls = tc;
|
plugin->cls = tc;
|
||||||
plugin->amount_round = &template_amount_round;
|
plugin->amount_round = &template_amount_round;
|
||||||
plugin->get_wire_details = &template_get_wire_details;
|
plugin->get_wire_details = &template_get_wire_details;
|
||||||
|
plugin->sign_wire_details = &template_sign_wire_details;
|
||||||
plugin->wire_validate = &template_wire_validate;
|
plugin->wire_validate = &template_wire_validate;
|
||||||
plugin->prepare_wire_transfer = &template_prepare_wire_transfer;
|
plugin->prepare_wire_transfer = &template_prepare_wire_transfer;
|
||||||
plugin->prepare_wire_transfer_cancel = &template_prepare_wire_transfer_cancel;
|
plugin->prepare_wire_transfer_cancel = &template_prepare_wire_transfer_cancel;
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "taler_wire_plugin.h"
|
#include "taler_wire_plugin.h"
|
||||||
#include "taler_bank_service.h"
|
#include "taler_bank_service.h"
|
||||||
|
#include "taler_signatures.h"
|
||||||
|
|
||||||
/* only for HTTP status codes */
|
/* only for HTTP status codes */
|
||||||
#include <microhttpd.h>
|
#include <microhttpd.h>
|
||||||
@ -285,6 +286,38 @@ test_get_wire_details (void *cls,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute purpose for signing.
|
||||||
|
*
|
||||||
|
* @param account number of the account
|
||||||
|
* @param bank_uri URI of the bank
|
||||||
|
* @param[out] mp purpose to be signed
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
compute_purpose (uint64_t account,
|
||||||
|
const char *bank_uri,
|
||||||
|
struct TALER_MasterWireDetailsPS *wsd)
|
||||||
|
{
|
||||||
|
struct GNUNET_HashContext *hc;
|
||||||
|
uint64_t n = GNUNET_htonll (account);
|
||||||
|
|
||||||
|
wsd->purpose.size = htonl (sizeof (struct TALER_MasterWireDetailsPS));
|
||||||
|
wsd->purpose.purpose = htonl (TALER_SIGNATURE_MASTER_TEST_DETAILS);
|
||||||
|
hc = GNUNET_CRYPTO_hash_context_start ();
|
||||||
|
GNUNET_CRYPTO_hash_context_read (hc,
|
||||||
|
"test",
|
||||||
|
strlen ("test") + 1);
|
||||||
|
GNUNET_CRYPTO_hash_context_read (hc,
|
||||||
|
&n,
|
||||||
|
sizeof (n));
|
||||||
|
GNUNET_CRYPTO_hash_context_read (hc,
|
||||||
|
bank_uri,
|
||||||
|
strlen (bank_uri) + 1);
|
||||||
|
GNUNET_CRYPTO_hash_context_finish (hc,
|
||||||
|
&wsd->h_sepa_details);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the given wire format JSON object is correctly formatted.
|
* Check if the given wire format JSON object is correctly formatted.
|
||||||
* Right now, the only thing we require is a field
|
* Right now, the only thing we require is a field
|
||||||
@ -319,6 +352,10 @@ test_wire_validate (void *cls,
|
|||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
|
/* FIXME: should check signature here in the future!
|
||||||
|
(note: right now the sig is not properly provided
|
||||||
|
by the exchange due to the way account data is
|
||||||
|
specified in the configuration) */
|
||||||
return GNUNET_YES;
|
return GNUNET_YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -510,6 +547,61 @@ execute_cb (void *cls,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sign wire transfer details in the plugin-specific format.
|
||||||
|
*
|
||||||
|
* @param cls closure
|
||||||
|
* @param in wire transfer details in JSON format
|
||||||
|
* @param key private signing key to use
|
||||||
|
* @param salt salt to add
|
||||||
|
* @param[out] sig where to write the signature
|
||||||
|
* @return #GNUNET_OK on success
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
test_sign_wire_details (void *cls,
|
||||||
|
const json_t *in,
|
||||||
|
const struct TALER_MasterPrivateKeyP *key,
|
||||||
|
const struct GNUNET_HashCode *salt,
|
||||||
|
struct TALER_MasterSignatureP *sig)
|
||||||
|
{
|
||||||
|
struct TALER_MasterWireDetailsPS wsd;
|
||||||
|
const char *bank_uri;
|
||||||
|
const char *type;
|
||||||
|
json_int_t account;
|
||||||
|
json_error_t err;
|
||||||
|
|
||||||
|
if (0 !=
|
||||||
|
json_unpack_ex ((json_t *) in,
|
||||||
|
&err,
|
||||||
|
0 /* flags */,
|
||||||
|
"{s:s, s:s, s:I}",
|
||||||
|
"type", &type,
|
||||||
|
"bank_uri", &bank_uri,
|
||||||
|
"account_number", &account))
|
||||||
|
{
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||||
|
"Failed to unpack JSON: %s (at %u)\n",
|
||||||
|
err.text,
|
||||||
|
err.position);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
if (0 != strcmp (type,
|
||||||
|
"test"))
|
||||||
|
{
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||||
|
"`type' must be `test' for test wire details\n");
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
compute_purpose (account,
|
||||||
|
bank_uri,
|
||||||
|
&wsd);
|
||||||
|
GNUNET_CRYPTO_eddsa_sign (&key->eddsa_priv,
|
||||||
|
&wsd.purpose,
|
||||||
|
&sig->eddsa_signature);
|
||||||
|
return GNUNET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute a wire transfer.
|
* Execute a wire transfer.
|
||||||
*
|
*
|
||||||
@ -682,6 +774,7 @@ libtaler_plugin_wire_test_init (void *cls)
|
|||||||
plugin->cls = tc;
|
plugin->cls = tc;
|
||||||
plugin->amount_round = &test_amount_round;
|
plugin->amount_round = &test_amount_round;
|
||||||
plugin->get_wire_details = &test_get_wire_details;
|
plugin->get_wire_details = &test_get_wire_details;
|
||||||
|
plugin->sign_wire_details = &test_sign_wire_details;
|
||||||
plugin->wire_validate = &test_wire_validate;
|
plugin->wire_validate = &test_wire_validate;
|
||||||
plugin->prepare_wire_transfer = &test_prepare_wire_transfer;
|
plugin->prepare_wire_transfer = &test_prepare_wire_transfer;
|
||||||
plugin->prepare_wire_transfer_cancel = &test_prepare_wire_transfer_cancel;
|
plugin->prepare_wire_transfer_cancel = &test_prepare_wire_transfer_cancel;
|
||||||
|
Loading…
Reference in New Issue
Block a user