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-keycheck.1 \
|
||||
taler-exchange-reservemod.1 \
|
||||
taler-exchange-wire.1 \
|
||||
taler.conf.5
|
||||
|
||||
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-keycheck \
|
||||
taler-exchange-reservemod \
|
||||
taler-exchange-sepa \
|
||||
taler-exchange-wire \
|
||||
taler-exchange-dbinit
|
||||
|
||||
taler_exchange_keyup_SOURCES = \
|
||||
@ -33,15 +33,15 @@ taler_auditor_sign_LDADD = \
|
||||
-lgnunetutil $(XLIB)
|
||||
|
||||
|
||||
taler_exchange_sepa_SOURCES = \
|
||||
taler-exchange-sepa.c
|
||||
taler_exchange_sepa_LDADD = \
|
||||
taler_exchange_wire_SOURCES = \
|
||||
taler-exchange-wire.c
|
||||
taler_exchange_wire_LDADD = \
|
||||
$(LIBGCRYPT_LIBS) \
|
||||
$(top_builddir)/src/util/libtalerutil.la \
|
||||
-lgnunetjson \
|
||||
-lgnunetutil \
|
||||
-ljansson $(XLIB)
|
||||
taler_exchange_sepa_LDFLAGS = $(POSTGRESQL_LDFLAGS)
|
||||
taler_exchange_wire_LDFLAGS = $(POSTGRESQL_LDFLAGS)
|
||||
|
||||
taler_exchange_keycheck_SOURCES = \
|
||||
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
|
||||
* the /wire/sepa response.
|
||||
* the /wire response.
|
||||
*/
|
||||
#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) */
|
||||
@ -762,11 +768,12 @@ struct TALER_RefreshCommitLinkP
|
||||
* @brief Information signed by the exchange's master
|
||||
* 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;
|
||||
|
||||
|
@ -113,6 +113,24 @@ struct TALER_WIRE_Plugin
|
||||
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
|
||||
*
|
||||
|
@ -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.
|
||||
*
|
||||
@ -365,14 +401,13 @@ verify_wire_sepa_signature_ok (const json_t *json,
|
||||
const struct TALER_MasterPublicKeyP *master_pub)
|
||||
{
|
||||
struct TALER_MasterSignatureP exchange_sig;
|
||||
struct TALER_MasterWireSepaDetailsPS mp;
|
||||
const char *receiver_name;
|
||||
struct TALER_MasterWireDetailsPS mp;
|
||||
const char *name;
|
||||
const char *iban;
|
||||
const char *bic;
|
||||
struct GNUNET_HashContext *hc;
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
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 ("bic", &bic),
|
||||
GNUNET_JSON_spec_end()
|
||||
@ -391,22 +426,10 @@ verify_wire_sepa_signature_ok (const json_t *json,
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
|
||||
mp.purpose.purpose = htonl (TALER_SIGNATURE_MASTER_SEPA_DETAILS);
|
||||
mp.purpose.size = htonl (sizeof (struct TALER_MasterWireSepaDetailsPS));
|
||||
hc = GNUNET_CRYPTO_hash_context_start ();
|
||||
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);
|
||||
|
||||
compute_purpose (name,
|
||||
iban,
|
||||
bic,
|
||||
&mp);
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_SEPA_DETAILS,
|
||||
&mp.purpose,
|
||||
@ -447,12 +470,12 @@ sepa_wire_validate (void *cls,
|
||||
"{"
|
||||
"s:s," /* type: sepa */
|
||||
"s:s," /* iban: IBAN */
|
||||
"s:s," /* receiver_name: beneficiary name */
|
||||
"s:s," /* name: beneficiary name */
|
||||
"s:s" /* bic: beneficiary bank's BIC */
|
||||
"}",
|
||||
"type", &type,
|
||||
"iban", &iban,
|
||||
"receiver_name", &name,
|
||||
"name", &name,
|
||||
"bic", &bic))
|
||||
{
|
||||
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.
|
||||
*
|
||||
@ -662,6 +749,7 @@ libtaler_plugin_wire_sepa_init (void *cls)
|
||||
plugin->cls = sc;
|
||||
plugin->amount_round = &sepa_amount_round;
|
||||
plugin->get_wire_details = &sepa_get_wire_details;
|
||||
plugin->sign_wire_details = &sepa_sign_wire_details;
|
||||
plugin->wire_validate = &sepa_wire_validate;
|
||||
plugin->prepare_wire_transfer = &sepa_prepare_wire_transfer;
|
||||
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
|
||||
* 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->amount_round = &template_amount_round;
|
||||
plugin->get_wire_details = &template_get_wire_details;
|
||||
plugin->sign_wire_details = &template_sign_wire_details;
|
||||
plugin->wire_validate = &template_wire_validate;
|
||||
plugin->prepare_wire_transfer = &template_prepare_wire_transfer;
|
||||
plugin->prepare_wire_transfer_cancel = &template_prepare_wire_transfer_cancel;
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "platform.h"
|
||||
#include "taler_wire_plugin.h"
|
||||
#include "taler_bank_service.h"
|
||||
#include "taler_signatures.h"
|
||||
|
||||
/* only for HTTP status codes */
|
||||
#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.
|
||||
* Right now, the only thing we require is a field
|
||||
@ -319,6 +352,10 @@ test_wire_validate (void *cls,
|
||||
GNUNET_break (0);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -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.
|
||||
*
|
||||
@ -682,6 +774,7 @@ libtaler_plugin_wire_test_init (void *cls)
|
||||
plugin->cls = tc;
|
||||
plugin->amount_round = &test_amount_round;
|
||||
plugin->get_wire_details = &test_get_wire_details;
|
||||
plugin->sign_wire_details = &test_sign_wire_details;
|
||||
plugin->wire_validate = &test_wire_validate;
|
||||
plugin->prepare_wire_transfer = &test_prepare_wire_transfer;
|
||||
plugin->prepare_wire_transfer_cancel = &test_prepare_wire_transfer_cancel;
|
||||
|
Loading…
Reference in New Issue
Block a user