first refactoring of JSON logic to address #4150 and #4237

This commit is contained in:
Christian Grothoff 2016-03-19 15:23:11 +01:00
parent d229f78da3
commit 0d1eced630
54 changed files with 887 additions and 2525 deletions

View File

@ -18,7 +18,7 @@
#
AC_PREREQ([2.69])
AC_INIT([taler-exchange], [0.0.0], [taler-bug@gnunet.org])
AC_CONFIG_SRCDIR([src/util/json.c])
AC_CONFIG_SRCDIR([src/util/util.c])
AC_CONFIG_HEADERS([taler_config.h])
# support for non-recursive builds
AM_INIT_AUTOMAKE([subdir-objects])
@ -354,14 +354,15 @@ AC_CONFIG_FILES([Makefile
doc/Makefile
doc/doxygen/Makefile
src/Makefile
src/include/Makefile
src/util/Makefile
src/pq/Makefile
src/bank-lib/Makefile
src/wire/Makefile
src/exchangedb/Makefile
src/exchange/Makefile
src/exchange-tools/Makefile
src/exchange-lib/Makefile
src/include/Makefile
src/json/Makefile
src/pq/Makefile
src/util/Makefile
src/wire/Makefile
])
AC_OUTPUT

View File

@ -15,7 +15,7 @@ if WALLET_ONLY
SUBDIRS = include util
else
SUBDIRS = include util $(PQ_DIR) $(BANK_LIB) wire exchangedb exchange exchange-tools
SUBDIRS = include util json $(PQ_DIR) $(BANK_LIB) wire exchangedb exchange exchange-tools
if HAVE_LIBCURL
SUBDIRS += exchange-lib
else

View File

@ -15,10 +15,11 @@ libtalerbank_la_LDFLAGS = \
libtalerbank_la_SOURCES = \
bank_api_context.c bank_api_context.h \
bank_api_json.c bank_api_json.h \
bank_api_admin.c
libtalerbank_la_LIBADD = \
$(top_builddir)/src/json/libtalerjson.la \
-lgnunetjson \
-lgnunetutil \
-ljansson \
$(XLIB)

View File

@ -24,8 +24,9 @@
#include <jansson.h>
#include <microhttpd.h> /* just for HTTP status codes */
#include <gnunet/gnunet_util_lib.h>
#include <gnunet/gnunet_json_lib.h>
#include "taler_bank_service.h"
#include "bank_api_json.h"
#include "taler_json_lib.h"
#include "bank_api_context.h"
#include "taler_signatures.h"
@ -173,9 +174,9 @@ TALER_BANK_admin_add_incoming (struct TALER_BANK_Context *bank,
admin_obj = json_pack ("{s:o, s:o,"
" s:I, s:I}",
"wtid", TALER_json_from_data (wtid,
"wtid", GNUNET_JSON_from_data (wtid,
sizeof (*wtid)),
"amount", TALER_json_from_amount (amount),
"amount", TALER_JSON_from_amount (amount),
"debit_account", (json_int_t) debit_account_no,
"credit_account", (json_int_t) credit_account_no);
aai = GNUNET_new (struct TALER_BANK_AdminAddIncomingHandle);

View File

@ -21,6 +21,7 @@
* @author Christian Grothoff
*/
#include "platform.h"
#include <jansson.h>
#include <curl/curl.h>
#include <gnunet/gnunet_util_lib.h>
#include "taler_bank_service.h"

View File

@ -1,525 +0,0 @@
/*
This file is part of TALER
Copyright (C) 2014, 2015 GNUnet e.V.
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
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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with
TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
*/
/**
* @file bank-lib/bank_api_json.c
* @brief functions to parse incoming requests (JSON snippets)
* @author Florian Dold
* @author Benedikt Mueller
* @author Christian Grothoff
*/
#include "platform.h"
#include "bank_api_json.h"
/**
* Navigate and parse data in a JSON tree.
*
* @param root the JSON node to start the navigation at.
* @param spec parse specification array
* @return offset in @a spec where parsing failed, -1 on success (!)
*/
static int
parse_json (json_t *root,
struct BAJ_Specification *spec)
{
int i;
json_t *pos; /* what's our current position? */
pos = root;
for (i=0;BAJ_CMD_END != spec[i].cmd;i++)
{
pos = json_object_get (root,
spec[i].field);
if (NULL == pos)
{
GNUNET_break_op (0);
return i;
}
switch (spec[i].cmd)
{
case BAJ_CMD_END:
GNUNET_assert (0);
return i;
case BAJ_CMD_AMOUNT:
if (GNUNET_OK !=
TALER_json_to_amount (pos,
spec[i].details.amount))
{
GNUNET_break_op (0);
return i;
}
break;
case BAJ_CMD_TIME_ABSOLUTE:
if (GNUNET_OK !=
TALER_json_to_abs (pos,
spec[i].details.abs_time))
{
GNUNET_break_op (0);
return i;
}
break;
case BAJ_CMD_STRING:
{
const char *str;
str = json_string_value (pos);
if (NULL == str)
{
GNUNET_break_op (0);
return i;
}
*spec[i].details.strptr = str;
}
break;
case BAJ_CMD_BINARY_FIXED:
{
const char *str;
int res;
str = json_string_value (pos);
if (NULL == str)
{
GNUNET_break_op (0);
return i;
}
res = GNUNET_STRINGS_string_to_data (str, strlen (str),
spec[i].details.fixed_data.dest,
spec[i].details.fixed_data.dest_size);
if (GNUNET_OK != res)
{
GNUNET_break_op (0);
return i;
}
}
break;
case BAJ_CMD_BINARY_VARIABLE:
{
const char *str;
size_t size;
void *data;
int res;
str = json_string_value (pos);
if (NULL == str)
{
GNUNET_break_op (0);
return i;
}
size = (strlen (str) * 5) / 8;
if (size >= 1024)
{
GNUNET_break_op (0);
return i;
}
data = GNUNET_malloc (size);
res = GNUNET_STRINGS_string_to_data (str,
strlen (str),
data,
size);
if (GNUNET_OK != res)
{
GNUNET_break_op (0);
GNUNET_free (data);
return i;
}
*spec[i].details.variable_data.dest_p = data;
*spec[i].details.variable_data.dest_size_p = size;
}
break;
case BAJ_CMD_RSA_PUBLIC_KEY:
{
size_t size;
const char *str;
int res;
void *buf;
str = json_string_value (pos);
if (NULL == str)
{
GNUNET_break_op (0);
return i;
}
size = (strlen (str) * 5) / 8;
buf = GNUNET_malloc (size);
res = GNUNET_STRINGS_string_to_data (str,
strlen (str),
buf,
size);
if (GNUNET_OK != res)
{
GNUNET_free (buf);
GNUNET_break_op (0);
return i;
}
*spec[i].details.rsa_public_key
= GNUNET_CRYPTO_rsa_public_key_decode (buf,
size);
GNUNET_free (buf);
if (NULL == spec[i].details.rsa_public_key)
{
GNUNET_break_op (0);
return i;
}
}
break;
case BAJ_CMD_RSA_SIGNATURE:
{
size_t size;
const char *str;
int res;
void *buf;
str = json_string_value (pos);
if (NULL == str)
{
GNUNET_break_op (0);
return i;
}
size = (strlen (str) * 5) / 8;
buf = GNUNET_malloc (size);
res = GNUNET_STRINGS_string_to_data (str,
strlen (str),
buf,
size);
if (GNUNET_OK != res)
{
GNUNET_free (buf);
GNUNET_break_op (0);
return i;
}
*spec[i].details.rsa_signature
= GNUNET_CRYPTO_rsa_signature_decode (buf,
size);
GNUNET_free (buf);
if (NULL == spec[i].details.rsa_signature)
return i;
}
break;
case BAJ_CMD_UINT16:
{
json_int_t val;
if (! json_is_integer (pos))
{
GNUNET_break_op (0);
return i;
}
val = json_integer_value (pos);
if ( (0 > val) || (val > UINT16_MAX) )
{
GNUNET_break_op (0);
return i;
}
*spec[i].details.u16 = (uint16_t) val;
}
break;
case BAJ_CMD_UINT64:
{
json_int_t val;
if (! json_is_integer (pos))
{
GNUNET_break_op (0);
return i;
}
val = json_integer_value (pos);
*spec[i].details.u64 = (uint64_t) val;
}
break;
case BAJ_CMD_JSON_OBJECT:
{
if (! (json_is_object (pos) || json_is_array (pos)) )
{
GNUNET_break_op (0);
return i;
}
json_incref (pos);
*spec[i].details.obj = pos;
}
break;
default:
GNUNET_break (0);
return i;
}
}
return -1; /* all OK! */
}
/**
* Free all elements allocated during a
* #BAJ_parse_json() operation.
*
* @param spec specification of the parse operation
* @param end number of elements in @a spec to process
*/
static void
parse_free (struct BAJ_Specification *spec,
int end)
{
int i;
for (i=0;i<end;i++)
{
switch (spec[i].cmd)
{
case BAJ_CMD_END:
GNUNET_assert (0);
return;
case BAJ_CMD_AMOUNT:
break;
case BAJ_CMD_TIME_ABSOLUTE:
break;
case BAJ_CMD_BINARY_FIXED:
break;
case BAJ_CMD_STRING:
break;
case BAJ_CMD_BINARY_VARIABLE:
GNUNET_free (*spec[i].details.variable_data.dest_p);
*spec[i].details.variable_data.dest_p = NULL;
*spec[i].details.variable_data.dest_size_p = 0;
break;
case BAJ_CMD_RSA_PUBLIC_KEY:
GNUNET_CRYPTO_rsa_public_key_free (*spec[i].details.rsa_public_key);
*spec[i].details.rsa_public_key = NULL;
break;
case BAJ_CMD_RSA_SIGNATURE:
GNUNET_CRYPTO_rsa_signature_free (*spec[i].details.rsa_signature);
*spec[i].details.rsa_signature = NULL;
break;
case BAJ_CMD_JSON_OBJECT:
json_decref (*spec[i].details.obj);
*spec[i].details.obj = NULL;
break;
default:
GNUNET_break (0);
break;
}
}
}
/**
* Navigate and parse data in a JSON tree.
*
* @param root the JSON node to start the navigation at.
* @param spec parse specification array
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
*/
int
BAJ_parse_json (const json_t *root,
struct BAJ_Specification *spec)
{
int ret;
ret = parse_json ((json_t *) root,
spec);
if (-1 == ret)
return GNUNET_OK;
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"JSON field `%s` (%d) had unexpected value\n",
spec[ret].field,
ret);
parse_free (spec, ret);
return GNUNET_SYSERR;
}
/**
* Free all elements allocated during a
* #BAJ_parse_json() operation.
*
* @param spec specification of the parse operation
*/
void
BAJ_parse_free (struct BAJ_Specification *spec)
{
int i;
for (i=0;BAJ_CMD_END != spec[i].cmd;i++) ;
parse_free (spec, i);
}
/**
* The expected field stores a string.
*
* @param name name of the JSON field
* @param strptr where to store a pointer to the field
*/
struct BAJ_Specification
BAJ_spec_string (const char *name,
const char **strptr)
{
struct BAJ_Specification ret =
{
.cmd = BAJ_CMD_STRING,
.field = name,
.details.strptr = strptr
};
return ret;
}
/**
* Specification for parsing an absolute time value.
*
* @param name name of the JSON field
* @param at where to store the absolute time found under @a name
*/
struct BAJ_Specification
BAJ_spec_absolute_time (const char *name,
struct GNUNET_TIME_Absolute *at)
{
struct BAJ_Specification ret =
{
.cmd = BAJ_CMD_TIME_ABSOLUTE,
.field = name,
.details.abs_time = at
};
return ret;
}
/**
* Specification for parsing an amount value.
*
* @param name name of the JSON field
* @param amount where to store the amount found under @a name
*/
struct BAJ_Specification
BAJ_spec_amount (const char *name,
struct TALER_Amount *amount)
{
struct BAJ_Specification ret =
{
.cmd = BAJ_CMD_AMOUNT,
.field = name,
.details.amount = amount
};
return ret;
}
/**
* 16-bit integer.
*
* @param name name of the JSON field
* @param[out] u16 where to store the integer found under @a name
*/
struct BAJ_Specification
BAJ_spec_uint16 (const char *name,
uint16_t *u16)
{
struct BAJ_Specification ret =
{
.cmd = BAJ_CMD_UINT16,
.field = name,
.details.u16 = u16
};
return ret;
}
/**
* 64-bit integer.
*
* @param name name of the JSON field
* @param[out] u64 where to store the integer found under @a name
*/
struct BAJ_Specification
BAJ_spec_uint64 (const char *name,
uint64_t *u64)
{
struct BAJ_Specification ret =
{
.cmd = BAJ_CMD_UINT64,
.field = name,
.details.u64 = u64
};
return ret;
}
/**
* JSON object.
*
* @param name name of the JSON field
* @param[out] jsonp where to store the JSON found under @a name
*/
struct BAJ_Specification
BAJ_spec_json (const char *name,
json_t **jsonp)
{
struct BAJ_Specification ret =
{
.cmd = BAJ_CMD_JSON_OBJECT,
.field = name,
.details.obj = jsonp
};
return ret;
}
/**
* Specification for parsing an RSA public key.
*
* @param name name of the JSON field
* @param pk where to store the RSA key found under @a name
*/
struct BAJ_Specification
BAJ_spec_rsa_public_key (const char *name,
struct GNUNET_CRYPTO_rsa_PublicKey **pk)
{
struct BAJ_Specification ret =
{
.cmd = BAJ_CMD_RSA_PUBLIC_KEY,
.field = name,
.details.rsa_public_key = pk
};
return ret;
}
/**
* Specification for parsing an RSA signature.
*
* @param name name of the JSON field
* @param sig where to store the RSA signature found under @a name
*/
struct BAJ_Specification
BAJ_spec_rsa_signature (const char *name,
struct GNUNET_CRYPTO_rsa_Signature **sig)
{
struct BAJ_Specification ret =
{
.cmd = BAJ_CMD_RSA_SIGNATURE,
.field = name,
.details.rsa_signature = sig
};
return ret;
}
/* end of bank_api_json.c */

View File

@ -1,352 +0,0 @@
/*
This file is part of TALER
Copyright (C) 2014, 2015 GNUnet e.V.
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
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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with
TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
*/
/**
* @file exchange-lib/exchange_api_json.h
* @brief functions to parse incoming requests (JSON snippets)
* @author Florian Dold
* @author Benedikt Mueller
* @author Christian Grothoff
*/
#include "platform.h"
#include <gnunet/gnunet_util_lib.h>
#include "taler_util.h"
#include <jansson.h>
/**
* Enumeration with the various commands for the
* #BAJ_parse_json interpreter.
*/
enum BAJ_Command
{
/**
* End of command list.
*/
BAJ_CMD_END,
/**
* Parse amount at current position.
*/
BAJ_CMD_AMOUNT,
/**
* Parse absolute time at current position.
*/
BAJ_CMD_TIME_ABSOLUTE,
/**
* Parse fixed binary value at current position.
*/
BAJ_CMD_BINARY_FIXED,
/**
* Parse variable-size binary value at current position.
*/
BAJ_CMD_BINARY_VARIABLE,
/**
* Parse RSA public key at current position.
*/
BAJ_CMD_RSA_PUBLIC_KEY,
/**
* Parse RSA signature at current position.
*/
BAJ_CMD_RSA_SIGNATURE,
/**
* Parse `const char *` JSON string at current position.
*/
BAJ_CMD_STRING,
/**
* Parse `uint16_t` integer at the current position.
*/
BAJ_CMD_UINT16,
/**
* Parse `uint64_t` integer at the current position.
*/
BAJ_CMD_UINT64,
/**
* Parse JSON object at the current position.
*/
BAJ_CMD_JSON_OBJECT,
/**
* Parse ??? at current position.
*/
BAJ_CMD_C
};
/**
* @brief Entry in parser specification for #BAJ_parse_json.
*/
struct BAJ_Specification
{
/**
* Command to execute.
*/
enum BAJ_Command cmd;
/**
* Name of the field to access.
*/
const char *field;
/**
* Further details for the command.
*/
union {
/**
* Where to store amount for #BAJ_CMD_AMOUNT.
*/
struct TALER_Amount *amount;
/**
* Where to store time, for #BAJ_CMD_TIME_ABSOLUTE.
*/
struct GNUNET_TIME_Absolute *abs_time;
/**
* Where to write binary data, for #BAJ_CMD_BINARY_FIXED.
*/
struct {
/**
* Where to write the data.
*/
void *dest;
/**
* How many bytes to write to @e dest.
*/
size_t dest_size;
} fixed_data;
/**
* Where to write binary data, for #BAJ_CMD_BINARY_VARIABLE.
*/
struct {
/**
* Where to store the pointer with the data (is allocated).
*/
void **dest_p;
/**
* Where to store the number of bytes allocated at `*dest`.
*/
size_t *dest_size_p;
} variable_data;
/**
* Where to store the RSA public key for #BAJ_CMD_RSA_PUBLIC_KEY
*/
struct GNUNET_CRYPTO_rsa_PublicKey **rsa_public_key;
/**
* Where to store the RSA signature for #BAJ_CMD_RSA_SIGNATURE
*/
struct GNUNET_CRYPTO_rsa_Signature **rsa_signature;
/**
* Details for #BAJ_CMD_EDDSA_SIGNATURE
*/
struct {
/**
* Where to store the purpose.
*/
struct GNUNET_CRYPTO_EccSignaturePurpose **purpose_p;
/**
* Key to verify the signature against.
*/
const struct GNUNET_CRYPTO_EddsaPublicKey *pub_key;
} eddsa_signature;
/**
* Where to store a pointer to the string.
*/
const char **strptr;
/**
* Where to store 16-bit integer.
*/
uint16_t *u16;
/**
* Where to store 64-bit integer.
*/
uint64_t *u64;
/**
* Where to store a JSON object.
*/
json_t **obj;
} details;
};
/**
* Navigate and parse data in a JSON tree.
*
* @param root the JSON node to start the navigation at.
* @param spec parse specification array
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
*/
int
BAJ_parse_json (const json_t *root,
struct BAJ_Specification *spec);
/**
* Free all elements allocated during a
* #BAJ_parse_json() operation.
*
* @param spec specification of the parse operation
*/
void
BAJ_parse_free (struct BAJ_Specification *spec);
/**
* End of a parser specification.
*/
#define BAJ_spec_end { .cmd = BAJ_CMD_END }
/**
* Fixed size object (in network byte order, encoded using Crockford
* Base32hex encoding).
*
* @param name name of the JSON field
* @param obj pointer where to write the data (type of `*obj` will determine size)
*/
#define BAJ_spec_fixed_auto(name,obj) { .cmd = BAJ_CMD_BINARY_FIXED, .field = name, .details.fixed_data.dest = obj, .details.fixed_data.dest_size = sizeof (*obj) }
/**
* Variable size object (in network byte order, encoded using Crockford
* Base32hex encoding).
*
* @param name name of the JSON field
* @param obj pointer where to write the data (a `void **`)
* @param size where to store the number of bytes allocated for @a obj (of type `size_t *`
*/
#define BAJ_spec_varsize(name,obj,size) { .cmd = BAJ_CMD_BINARY_VARIABLE, .field = name, .details.variable_data.dest_p = obj, .details.variable_data.dest_size_p = size }
/**
* The expected field stores a string.
*
* @param name name of the JSON field
* @param strptr where to store a pointer to the field
*/
struct BAJ_Specification
BAJ_spec_string (const char *name,
const char **strptr);
/**
* Absolute time.
*
* @param name name of the JSON field
* @param[out] at where to store the absolute time found under @a name
*/
struct BAJ_Specification
BAJ_spec_absolute_time (const char *name,
struct GNUNET_TIME_Absolute *at);
/**
* 16-bit integer.
*
* @param name name of the JSON field
* @param[out] u16 where to store the integer found under @a name
*/
struct BAJ_Specification
BAJ_spec_uint16 (const char *name,
uint16_t *u16);
/**
* 64-bit integer.
*
* @param name name of the JSON field
* @param[out] u64 where to store the integer found under @a name
*/
struct BAJ_Specification
BAJ_spec_uint64 (const char *name,
uint64_t *u64);
/**
* JSON object.
*
* @param name name of the JSON field
* @param[out] jsonp where to store the JSON found under @a name
*/
struct BAJ_Specification
BAJ_spec_json (const char *name,
json_t **jsonp);
/**
* Specification for parsing an amount value.
*
* @param name name of the JSON field
* @param amount where to store the amount under @a name
*/
struct BAJ_Specification
BAJ_spec_amount (const char *name,
struct TALER_Amount *amount);
/**
* Specification for parsing an RSA public key.
*
* @param name name of the JSON field
* @param pk where to store the RSA key found under @a name
*/
struct BAJ_Specification
BAJ_spec_rsa_public_key (const char *name,
struct GNUNET_CRYPTO_rsa_PublicKey **pk);
/**
* Specification for parsing an RSA signature.
*
* @param name name of the JSON field
* @param sig where to store the RSA signature found under @a name
*/
struct BAJ_Specification
BAJ_spec_rsa_signature (const char *name,
struct GNUNET_CRYPTO_rsa_Signature **sig);
/* end of exchange_api_json.h */

View File

@ -28,6 +28,9 @@ libtalerexchange_la_SOURCES = \
exchange_api_wire_deposits.c
libtalerexchange_la_LIBADD = \
$(top_builddir)/src/json/libtalerjson.la \
$(top_builddir)/src/util/libtalerutil.la \
-lgnunetjson \
-lgnunetutil \
-ljansson \
$(XLIB)
@ -51,6 +54,7 @@ test_exchange_api_SOURCES = \
test_exchange_api_LDADD = \
libtalerexchange.la \
$(LIBGCRYPT_LIBS) \
$(top_builddir)/src/json/libtalerjson.la \
$(top_builddir)/src/util/libtalerutil.la \
-lgnunetutil \
-ljansson

View File

@ -24,6 +24,8 @@
#include <jansson.h>
#include <microhttpd.h> /* just for HTTP status codes */
#include <gnunet/gnunet_util_lib.h>
#include <gnunet/gnunet_json_lib.h>
#include "taler_json_lib.h"
#include "taler_exchange_service.h"
#include "exchange_api_json.h"
#include "exchange_api_context.h"
@ -174,7 +176,7 @@ TALER_EXCHANGE_admin_add_incoming (struct TALER_EXCHANGE_Handle *exchange,
CURL *eh;
GNUNET_assert (GNUNET_OK ==
TALER_round_abs_time (&execution_date));
GNUNET_TIME_round_abs (&execution_date));
if (GNUNET_YES !=
MAH_handle_is_ready (exchange))
{
@ -183,10 +185,10 @@ TALER_EXCHANGE_admin_add_incoming (struct TALER_EXCHANGE_Handle *exchange,
}
admin_obj = json_pack ("{s:o, s:o," /* reserve_pub/amount */
" s:o, s:O}", /* execution_Date/wire */
"reserve_pub", TALER_json_from_data (reserve_pub,
"reserve_pub", GNUNET_JSON_from_data (reserve_pub,
sizeof (*reserve_pub)),
"amount", TALER_json_from_amount (amount),
"execution_date", TALER_json_from_abs (execution_date),
"amount", TALER_JSON_from_amount (amount),
"execution_date", GNUNET_JSON_from_time_abs (execution_date),
"wire", wire);
aai = GNUNET_new (struct TALER_EXCHANGE_AdminAddIncomingHandle);
aai->exchange = exchange;

View File

@ -25,6 +25,8 @@
#include <jansson.h>
#include <microhttpd.h> /* just for HTTP status codes */
#include <gnunet/gnunet_util_lib.h>
#include <gnunet/gnunet_json_lib.h>
#include "taler_json_lib.h"
#include "taler_exchange_service.h"
#include "exchange_api_common.h"
#include "exchange_api_json.h"
@ -411,7 +413,7 @@ TALER_EXCHANGE_deposit (struct TALER_EXCHANGE_Handle *exchange,
struct GNUNET_HashCode h_wire;
struct TALER_Amount amount_without_fee;
(void) TALER_round_abs_time (&wire_deadline);
(void) GNUNET_TIME_round_abs (&wire_deadline);
if (GNUNET_YES !=
MAH_handle_is_ready (exchange))
{
@ -420,7 +422,7 @@ TALER_EXCHANGE_deposit (struct TALER_EXCHANGE_Handle *exchange,
}
/* initialize h_wire */
if (GNUNET_OK !=
TALER_hash_json (wire_details,
TALER_JSON_hash (wire_details,
&h_wire))
{
GNUNET_break (0);
@ -468,23 +470,23 @@ TALER_EXCHANGE_deposit (struct TALER_EXCHANGE_Handle *exchange,
" s:I, s:o," /* transaction id, merchant_pub */
" s:o, s:o," /* refund_deadline, wire_deadline */
" s:o}", /* coin_sig */
"f", TALER_json_from_amount (amount),
"f", TALER_JSON_from_amount (amount),
"wire", wire_details,
"H_wire", TALER_json_from_data (&h_wire,
"H_wire", GNUNET_JSON_from_data (&h_wire,
sizeof (h_wire)),
"H_contract", TALER_json_from_data (h_contract,
"H_contract", GNUNET_JSON_from_data (h_contract,
sizeof (struct GNUNET_HashCode)),
"coin_pub", TALER_json_from_data (coin_pub,
"coin_pub", GNUNET_JSON_from_data (coin_pub,
sizeof (*coin_pub)),
"denom_pub", TALER_json_from_rsa_public_key (denom_pub->rsa_public_key),
"ub_sig", TALER_json_from_rsa_signature (denom_sig->rsa_signature),
"timestamp", TALER_json_from_abs (timestamp),
"denom_pub", GNUNET_JSON_from_rsa_public_key (denom_pub->rsa_public_key),
"ub_sig", GNUNET_JSON_from_rsa_signature (denom_sig->rsa_signature),
"timestamp", GNUNET_JSON_from_time_abs (timestamp),
"transaction_id", (json_int_t) transaction_id,
"merchant_pub", TALER_json_from_data (merchant_pub,
"merchant_pub", GNUNET_JSON_from_data (merchant_pub,
sizeof (*merchant_pub)),
"refund_deadline", TALER_json_from_abs (refund_deadline),
"edate", TALER_json_from_abs (wire_deadline),
"coin_sig", TALER_json_from_data (coin_sig,
"refund_deadline", GNUNET_JSON_from_time_abs (refund_deadline),
"edate", GNUNET_JSON_from_time_abs (wire_deadline),
"coin_sig", GNUNET_JSON_from_data (coin_sig,
sizeof (*coin_sig))
);

View File

@ -24,6 +24,7 @@
#include <jansson.h>
#include <microhttpd.h> /* just for HTTP status codes */
#include <gnunet/gnunet_util_lib.h>
#include <gnunet/gnunet_json_lib.h>
#include "taler_exchange_service.h"
#include "exchange_api_common.h"
#include "exchange_api_json.h"
@ -296,16 +297,16 @@ TALER_EXCHANGE_deposit_wtid (struct TALER_EXCHANGE_Handle *exchange,
deposit_wtid_obj = json_pack ("{s:o, s:o," /* H_wire, H_contract */
" s:o, s:I," /* coin_pub, transaction_id */
" s:o, s:o}", /* merchant_pub, merchant_sig */
"H_wire", TALER_json_from_data (h_wire,
"H_wire", GNUNET_JSON_from_data (h_wire,
sizeof (struct GNUNET_HashCode)),
"H_contract", TALER_json_from_data (h_contract,
"H_contract", GNUNET_JSON_from_data (h_contract,
sizeof (struct GNUNET_HashCode)),
"coin_pub", TALER_json_from_data (coin_pub,
"coin_pub", GNUNET_JSON_from_data (coin_pub,
sizeof (*coin_pub)),
"transaction_id", (json_int_t) transaction_id,
"merchant_pub", TALER_json_from_data (&dtp.merchant,
"merchant_pub", GNUNET_JSON_from_data (&dtp.merchant,
sizeof (struct TALER_MerchantPublicKeyP)),
"merchant_sig", TALER_json_from_data (&merchant_sig,
"merchant_sig", GNUNET_JSON_from_data (&merchant_sig,
sizeof (merchant_sig)));
dwh = GNUNET_new (struct TALER_EXCHANGE_DepositWtidHandle);

View File

@ -22,6 +22,7 @@
*/
#include "platform.h"
#include "exchange_api_json.h"
#include "taler_json_lib.h"
/**
* Navigate and parse data in a JSON tree.
@ -53,24 +54,39 @@ parse_json (json_t *root,
GNUNET_assert (0);
return i;
case MAJ_CMD_AMOUNT:
if (GNUNET_OK !=
TALER_json_to_amount (pos,
spec[i].details.amount))
{
GNUNET_break_op (0);
return i;
}
break;
case MAJ_CMD_TIME_ABSOLUTE:
if (GNUNET_OK !=
TALER_json_to_abs (pos,
spec[i].details.abs_time))
{
GNUNET_break_op (0);
return i;
}
break;
struct GNUNET_JSON_Specification nspec[] = {
TALER_JSON_spec_amount (NULL, spec[i].details.amount),
GNUNET_JSON_spec_end ()
};
if (GNUNET_OK !=
GNUNET_JSON_parse (pos,
nspec,
NULL, NULL))
{
GNUNET_break_op (0);
return i;
}
break;
}
case MAJ_CMD_TIME_ABSOLUTE:
{
struct GNUNET_JSON_Specification nspec[] = {
GNUNET_JSON_spec_absolute_time (NULL, spec[i].details.abs_time),
GNUNET_JSON_spec_end ()
};
if (GNUNET_OK !=
GNUNET_JSON_parse (pos,
nspec,
NULL, NULL))
{
GNUNET_break_op (0);
return i;
}
break;
}
case MAJ_CMD_STRING:
{
const char *str;

View File

@ -24,6 +24,8 @@
#include <jansson.h>
#include <microhttpd.h> /* just for HTTP status codes */
#include <gnunet/gnunet_util_lib.h>
#include <gnunet/gnunet_json_lib.h>
#include "taler_json_lib.h"
#include "taler_exchange_service.h"
#include "exchange_api_common.h"
#include "exchange_api_json.h"
@ -1373,17 +1375,17 @@ melted_coin_to_json (const struct GNUNET_HashCode *melt_session_hash,
&confirm_sig.eddsa_signature);
return json_pack ("{s:o, s:o, s:o, s:o, s:o}",
"coin_pub",
TALER_json_from_data (&melt.coin_pub,
GNUNET_JSON_from_data (&melt.coin_pub,
sizeof (melt.coin_pub)),
"denom_pub",
TALER_json_from_rsa_public_key (mc->pub_key.rsa_public_key),
GNUNET_JSON_from_rsa_public_key (mc->pub_key.rsa_public_key),
"denom_sig",
TALER_json_from_rsa_signature (mc->sig.rsa_signature),
GNUNET_JSON_from_rsa_signature (mc->sig.rsa_signature),
"confirm_sig",
TALER_json_from_data (&confirm_sig,
GNUNET_JSON_from_data (&confirm_sig,
sizeof (confirm_sig)),
"value_with_fee",
TALER_json_from_amount (&mc->melt_amount_with_fee));
TALER_JSON_from_amount (&mc->melt_amount_with_fee));
}
@ -1472,7 +1474,7 @@ TALER_EXCHANGE_refresh_melt (struct TALER_EXCHANGE_Handle *exchange,
GNUNET_CRYPTO_ecdhe_key_get_public (&mc->transfer_priv[j].ecdhe_priv,
&transfer_pub.ecdhe_pub);
json_array_append (tmp,
TALER_json_from_data (&transfer_pub,
GNUNET_JSON_from_data (&transfer_pub,
sizeof (transfer_pub)));
}
json_array_append (transfer_pubs,
@ -1497,7 +1499,7 @@ TALER_EXCHANGE_refresh_melt (struct TALER_EXCHANGE_Handle *exchange,
&trans_sec,
&els));
json_array_append (tmp,
TALER_json_from_data (&els,
GNUNET_JSON_from_data (&els,
sizeof (els)));
}
json_array_append (secret_encs,
@ -1508,7 +1510,7 @@ TALER_EXCHANGE_refresh_melt (struct TALER_EXCHANGE_Handle *exchange,
for (i=0;i<md->num_fresh_coins;i++)
{
json_array_append (new_denoms,
TALER_json_from_rsa_public_key
GNUNET_JSON_from_rsa_public_key
(md->fresh_pks[i].rsa_public_key));
}
@ -1533,7 +1535,7 @@ TALER_EXCHANGE_refresh_melt (struct TALER_EXCHANGE_Handle *exchange,
&buf_len);
GNUNET_assert (NULL != buf);
json_array_append (tmp,
TALER_json_from_data (buf,
GNUNET_JSON_from_data (buf,
buf_len));
GNUNET_free (buf);
GNUNET_free (rle);
@ -1564,7 +1566,7 @@ TALER_EXCHANGE_refresh_melt (struct TALER_EXCHANGE_Handle *exchange,
md->fresh_pks[i].rsa_public_key,
&coin_ev);
json_array_append (tmp,
TALER_json_from_data (coin_ev,
GNUNET_JSON_from_data (coin_ev,
coin_ev_size));
GNUNET_free (coin_ev);
}
@ -1975,7 +1977,7 @@ TALER_EXCHANGE_refresh_reveal (struct TALER_EXCHANGE_Handle *exchange,
const struct MeltedCoin *mc = &md->melted_coins[i];
json_array_append (tmp,
TALER_json_from_data (&mc->transfer_priv[j],
GNUNET_JSON_from_data (&mc->transfer_priv[j],
sizeof (struct TALER_TransferPrivateKeyP)));
}
json_array_append (transfer_privs,
@ -1985,7 +1987,7 @@ TALER_EXCHANGE_refresh_reveal (struct TALER_EXCHANGE_Handle *exchange,
/* build main JSON request */
reveal_obj = json_pack ("{s:o, s:o}",
"session_hash",
TALER_json_from_data (&md->melt_session_hash,
GNUNET_JSON_from_data (&md->melt_session_hash,
sizeof (struct GNUNET_HashCode)),
"transfer_privs",
transfer_privs);

View File

@ -24,6 +24,7 @@
#include <jansson.h>
#include <microhttpd.h> /* just for HTTP status codes */
#include <gnunet/gnunet_util_lib.h>
#include <gnunet/gnunet_json_lib.h>
#include "taler_exchange_service.h"
#include "exchange_api_json.h"
#include "exchange_api_context.h"
@ -859,12 +860,12 @@ TALER_EXCHANGE_reserve_withdraw (struct TALER_EXCHANGE_Handle *exchange,
&reserve_sig.eddsa_signature));
withdraw_obj = json_pack ("{s:o, s:o," /* denom_pub and coin_ev */
" s:o, s:o}",/* reserve_pub and reserve_sig */
"denom_pub", TALER_json_from_rsa_public_key (pk->key.rsa_public_key),
"coin_ev", TALER_json_from_data (coin_ev,
"denom_pub", GNUNET_JSON_from_rsa_public_key (pk->key.rsa_public_key),
"coin_ev", GNUNET_JSON_from_data (coin_ev,
coin_ev_size),
"reserve_pub", TALER_json_from_data (&wsh->reserve_pub,
"reserve_pub", GNUNET_JSON_from_data (&wsh->reserve_pub,
sizeof (struct TALER_ReservePublicKeyP)),
"reserve_sig", TALER_json_from_data (&reserve_sig,
"reserve_sig", GNUNET_JSON_from_data (&reserve_sig,
sizeof (reserve_sig)));
GNUNET_free (coin_ev);

View File

@ -25,11 +25,11 @@
#include <microhttpd.h> /* just for HTTP status codes */
#include <gnunet/gnunet_util_lib.h>
#include "taler_exchange_service.h"
#include "taler_wire_plugin.h"
#include "exchange_api_common.h"
#include "exchange_api_json.h"
#include "exchange_api_context.h"
#include "exchange_api_handle.h"
#include "taler_signatures.h"
/**
@ -82,93 +82,6 @@ struct TALER_EXCHANGE_WireHandle
};
/**
* Verify that the signature on the "200 OK" response
* for /wire/test from the exchange is valid.
* Accepts everything.
*
* @param wh wire handle
* @param json json reply with the signature
* @return #GNUNET_SYSERR if @a json is invalid,
* #GNUNET_NO if the method is unknown,
* #GNUNET_OK if the json is valid
*/
static int
verify_wire_test_signature_ok (const struct TALER_EXCHANGE_WireHandle *wh,
json_t *json)
{
return GNUNET_OK;
}
/**
* Verify that the signature on the "200 OK" response
* for /wire/sepa from the exchange is valid.
*
* @param wh wire handle
* @param json json reply with the signature
* @return #GNUNET_SYSERR if @a json is invalid,
* #GNUNET_NO if the method is unknown,
* #GNUNET_OK if the json is valid
*/
static int
verify_wire_sepa_signature_ok (const struct TALER_EXCHANGE_WireHandle *wh,
json_t *json)
{
struct TALER_MasterSignatureP exchange_sig;
struct TALER_MasterWireSepaDetailsPS mp;
const char *receiver_name;
const char *iban;
const char *bic;
const struct TALER_EXCHANGE_Keys *key_state;
struct GNUNET_HashContext *hc;
struct MAJ_Specification spec[] = {
MAJ_spec_fixed_auto ("sig", &exchange_sig),
MAJ_spec_string ("receiver_name", &receiver_name),
MAJ_spec_string ("iban", &iban),
MAJ_spec_string ("bic", &bic),
MAJ_spec_end
};
if (GNUNET_OK !=
MAJ_parse_json (json,
spec))
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
key_state = TALER_EXCHANGE_get_keys (wh->exchange);
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);
if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_SEPA_DETAILS,
&mp.purpose,
&exchange_sig.eddsa_signature,
&key_state->master_pub.eddsa_pub))
{
GNUNET_break_op (0);
MAJ_parse_free (spec);
return GNUNET_SYSERR;
}
MAJ_parse_free (spec);
return GNUNET_OK;
}
/**
* Verify that the signature on the "200 OK" response
* for /wire/METHOD from the exchange is valid.
@ -185,37 +98,33 @@ verify_wire_method_signature_ok (const struct TALER_EXCHANGE_WireHandle *wh,
const char *method,
json_t *json)
{
struct
const struct TALER_EXCHANGE_Keys *key_state;
struct TALER_WIRE_Plugin *plugin;
char *lib_name;
int ret;
key_state = TALER_EXCHANGE_get_keys (wh->exchange);
(void) GNUNET_asprintf (&lib_name,
"libtaler_plugin_wire_%s",
method);
plugin = GNUNET_PLUGIN_load (lib_name,
NULL);
if (NULL == plugin)
{
/**
* Name fo the method.
*/
const char *method;
/**
* Handler to invoke to verify signature.
*
* @param wh wire handle with key material
* @param json json reply with signature to verify
*/
int (*handler)(const struct TALER_EXCHANGE_WireHandle *wh,
json_t *json);
} handlers[] = {
{ "test", &verify_wire_test_signature_ok },
{ "sepa", &verify_wire_sepa_signature_ok },
{ NULL, NULL }
};
unsigned int i;
for (i=0;NULL != handlers[i].method; i++)
if (0 == strcasecmp (handlers[i].method,
method))
return handlers[i].handler (wh,
json);
GNUNET_free (lib_name);
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Wire transfer method `%s' not supported\n",
method);
return GNUNET_NO;
}
plugin->library_name = lib_name;
ret = plugin->wire_validate (plugin->cls,
json,
&key_state->master_pub);
GNUNET_PLUGIN_unload (lib_name,
plugin);
GNUNET_free (lib_name);
return (GNUNET_YES == ret) ? GNUNET_OK : GNUNET_SYSERR;
}
@ -312,6 +221,7 @@ handle_wire_method_finished (void *cls,
json_string_value (json_array_get (wh->methods,
wh->methods_off-1)),
json);
json_decref (json);
/* trigger request for the next /wire/method */
request_wire_method (wh);
}

View File

@ -24,6 +24,7 @@
#include <jansson.h>
#include <microhttpd.h> /* just for HTTP status codes */
#include <gnunet/gnunet_util_lib.h>
#include <gnunet/gnunet_json_lib.h>
#include "taler_exchange_service.h"
#include "exchange_api_common.h"
#include "exchange_api_json.h"

View File

@ -1,6 +1,9 @@
{
"receiver_name": "Max Mustermann",
"iban": "DE89370400440532013000",
"type": "sepa",
"bic": "COBADEFF370",
"sig": "8M5YJXM68PRAXKH76HYEBCJW657B23JA0RFGNDMZK2379YZMT626H1BN89KC0M1KJBWGYEN5Z763Q0Y7MCTZQ6BPPT7D9KFCTW60C10"
"address": "Musterstadt",
"iban": "DE89370400440532013000",
"receiver_name": "Max Musterman",
"salt": "J5AP2BJ8MQAM1WQYQ9YPTAHZVTDXCT3RKHX851S5Q2A42T11K796MNMKJ78VBGDKCFMETMBDPM35D81NCCN77YRW92GDFSQ6P4CZ720",
"sig": "FF4JZ1FPNVEFPM6ZXD3QN1M225T9X912PX1GJDWGGJX6KBSTR2EZHK24E1PYW7P64YGGQG7Q9HJW0XE36HBBYZWXW83PKVZEYNVG038"
}

View File

@ -23,6 +23,7 @@
#include "taler_util.h"
#include "taler_signatures.h"
#include "taler_exchange_service.h"
#include "taler_json_lib.h"
#include <gnunet/gnunet_util_lib.h>
#include <microhttpd.h>
@ -1502,7 +1503,7 @@ interpreter_run (void *cls,
return;
}
execution_date = GNUNET_TIME_absolute_get ();
TALER_round_abs_time (&execution_date);
GNUNET_TIME_round_abs (&execution_date);
cmd->details.admin_add_incoming.aih
= TALER_EXCHANGE_admin_add_incoming (exchange,
&reserve_pub,
@ -1664,7 +1665,7 @@ interpreter_run (void *cls,
fail (is);
return;
}
TALER_hash_json (contract,
TALER_JSON_hash (contract,
&h_contract);
wire = json_loads (cmd->details.deposit.wire_details,
JSON_REJECT_DUPLICATES,
@ -1698,7 +1699,7 @@ interpreter_run (void *cls,
wire_deadline = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_DAYS);
timestamp = GNUNET_TIME_absolute_get ();
TALER_round_abs_time (&timestamp);
GNUNET_TIME_round_abs (&timestamp);
{
struct TALER_DepositRequestPS dr;
@ -1706,7 +1707,7 @@ interpreter_run (void *cls,
dr.purpose.size = htonl (sizeof (struct TALER_DepositRequestPS));
dr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT);
dr.h_contract = h_contract;
TALER_hash_json (wire,
TALER_JSON_hash (wire,
&dr.h_wire);
dr.timestamp = GNUNET_TIME_absolute_hton (timestamp);
dr.refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline);
@ -1964,14 +1965,14 @@ interpreter_run (void *cls,
JSON_REJECT_DUPLICATES,
NULL);
GNUNET_assert (NULL != wire);
TALER_hash_json (wire,
TALER_JSON_hash (wire,
&h_wire);
json_decref (wire);
contract = json_loads (ref->details.deposit.contract,
JSON_REJECT_DUPLICATES,
NULL);
GNUNET_assert (NULL != contract);
TALER_hash_json (contract,
TALER_JSON_hash (contract,
&h_contract);
json_decref (contract);
cmd->details.deposit_wtid.dwh
@ -2349,7 +2350,7 @@ run (void *cls,
{ .oc = OC_ADMIN_ADD_INCOMING,
.label = "create-reserve-1",
.expected_response_code = MHD_HTTP_OK,
.details.admin_add_incoming.wire = "{ \"type\":\"TEST\", \"bank\":\"source bank\", \"account_number\":42 }",
.details.admin_add_incoming.wire = "{ \"type\":\"test\", \"bank\":\"source bank\", \"account_number\":42 }",
.details.admin_add_incoming.amount = "EUR:5.01" },
/* Withdraw a 5 EUR coin, at fee of 1 ct */
{ .oc = OC_WITHDRAW_SIGN,
@ -2370,7 +2371,7 @@ run (void *cls,
.expected_response_code = MHD_HTTP_OK,
.details.deposit.amount = "EUR:5",
.details.deposit.coin_ref = "withdraw-coin-1",
.details.deposit.wire_details = "{ \"type\":\"TEST\", \"bank\":\"dest bank\", \"account_number\":42 }",
.details.deposit.wire_details = "{ \"type\":\"test\", \"bank\":\"dest bank\", \"account_number\":42 }",
.details.deposit.contract = "{ \"items\": [ { \"name\":\"ice cream\", \"value\":1 } ] }",
.details.deposit.transaction_id = 1 },
@ -2387,7 +2388,7 @@ run (void *cls,
.expected_response_code = MHD_HTTP_FORBIDDEN,
.details.deposit.amount = "EUR:5",
.details.deposit.coin_ref = "withdraw-coin-1",
.details.deposit.wire_details = "{ \"type\":\"TEST\", \"bank\":\"dest bank\", \"account_number\":43 }",
.details.deposit.wire_details = "{ \"type\":\"test\", \"bank\":\"dest bank\", \"account_number\":43 }",
.details.deposit.contract = "{ \"items\": [ { \"name\":\"ice cream\", \"value\":1 } ] }",
.details.deposit.transaction_id = 1 },
/* Try to double-spend the 5 EUR coin at the same merchant (but different
@ -2397,7 +2398,7 @@ run (void *cls,
.expected_response_code = MHD_HTTP_FORBIDDEN,
.details.deposit.amount = "EUR:5",
.details.deposit.coin_ref = "withdraw-coin-1",
.details.deposit.wire_details = "{ \"type\":\"TEST\", \"bank\":\"dest bank\", \"account_number\":42 }",
.details.deposit.wire_details = "{ \"type\":\"test\", \"bank\":\"dest bank\", \"account_number\":42 }",
.details.deposit.contract = "{ \"items\": [ { \"name\":\"ice cream\", \"value\":1 } ] }",
.details.deposit.transaction_id = 2 },
/* Try to double-spend the 5 EUR coin at the same merchant (but different
@ -2407,7 +2408,7 @@ run (void *cls,
.expected_response_code = MHD_HTTP_FORBIDDEN,
.details.deposit.amount = "EUR:5",
.details.deposit.coin_ref = "withdraw-coin-1",
.details.deposit.wire_details = "{ \"type\":\"TEST\", \"bank\":\"dest bank\", \"account_number\":42 }",
.details.deposit.wire_details = "{ \"type\":\"test\", \"bank\":\"dest bank\", \"account_number\":42 }",
.details.deposit.contract = "{ \"items\":[{ \"name\":\"ice cream\", \"value\":2 } ] }",
.details.deposit.transaction_id = 1 },
@ -2417,7 +2418,7 @@ run (void *cls,
{ .oc = OC_ADMIN_ADD_INCOMING,
.label = "refresh-create-reserve-1",
.expected_response_code = MHD_HTTP_OK,
.details.admin_add_incoming.wire = "{ \"type\":\"TEST\", \"bank\":\"source bank\", \"account_number\":424 }",
.details.admin_add_incoming.wire = "{ \"type\":\"test\", \"bank\":\"source bank\", \"account_number\":424 }",
.details.admin_add_incoming.amount = "EUR:5.01" },
/* Withdraw a 5 EUR coin, at fee of 1 ct */
{ .oc = OC_WITHDRAW_SIGN,
@ -2432,7 +2433,7 @@ run (void *cls,
.expected_response_code = MHD_HTTP_OK,
.details.deposit.amount = "EUR:1",
.details.deposit.coin_ref = "refresh-withdraw-coin-1",
.details.deposit.wire_details = "{ \"type\":\"TEST\", \"bank\":\"dest bank\", \"account_number\":42 }",
.details.deposit.wire_details = "{ \"type\":\"test\", \"bank\":\"dest bank\", \"account_number\":42 }",
.details.deposit.contract = "{ \"items\" : [ { \"name\":\"ice cream\", \"value\":\"EUR:1\" } ] }",
.details.deposit.transaction_id = 42421 },

View File

@ -38,7 +38,9 @@ taler_exchange_sepa_SOURCES = \
taler_exchange_sepa_LDADD = \
$(LIBGCRYPT_LIBS) \
$(top_builddir)/src/util/libtalerutil.la \
-lgnunetutil -ljansson $(XLIB)
-lgnunetjson \
-lgnunetutil \
-ljansson $(XLIB)
taler_exchange_sepa_LDFLAGS = $(POSTGRESQL_LDFLAGS)
taler_exchange_keycheck_SOURCES = \

View File

@ -518,7 +518,7 @@ exchange_keys_update_signkeys ()
"must be longer than signkey_duration");
return GNUNET_SYSERR;
}
TALER_round_rel_time (&signkey_duration);
GNUNET_TIME_round_rel (&signkey_duration);
GNUNET_asprintf (&signkey_dir,
"%s" DIR_SEPARATOR_STR TALER_EXCHANGEDB_DIR_SIGNING_KEYS,
exchange_directory);
@ -600,7 +600,7 @@ get_cointype_params (const char *ct,
"duration_withdraw");
return GNUNET_SYSERR;
}
TALER_round_rel_time (&params->duration_withdraw);
GNUNET_TIME_round_rel (&params->duration_withdraw);
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_time (kcfg,
ct,
@ -612,7 +612,7 @@ get_cointype_params (const char *ct,
"duration_spend");
return GNUNET_SYSERR;
}
TALER_round_rel_time (&params->duration_spend);
GNUNET_TIME_round_rel (&params->duration_spend);
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_time (kcfg,
ct,
@ -624,7 +624,7 @@ get_cointype_params (const char *ct,
"duration_legal");
return GNUNET_SYSERR;
}
TALER_round_rel_time (&params->duration_legal);
GNUNET_TIME_round_rel (&params->duration_legal);
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_time (kcfg,
ct,
@ -636,7 +636,7 @@ get_cointype_params (const char *ct,
"exchange_denom_duration_overlap");
return GNUNET_SYSERR;
}
TALER_round_rel_time (&params->duration_overlap);
GNUNET_TIME_round_rel (&params->duration_overlap);
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_number (kcfg,
ct,
@ -927,7 +927,7 @@ main (int argc,
{
now = GNUNET_TIME_absolute_get ();
}
TALER_round_abs_time (&now);
GNUNET_TIME_round_abs (&now);
kcfg = TALER_config_load (exchange_directory);
if (NULL == kcfg)
@ -1017,7 +1017,7 @@ main (int argc,
_("must not be zero"));
return GNUNET_SYSERR;
}
TALER_round_rel_time (&lookahead_sign);
GNUNET_TIME_round_rel (&lookahead_sign);
lookahead_sign_stamp = GNUNET_TIME_absolute_add (now,
lookahead_sign);

View File

@ -20,6 +20,7 @@
*/
#include <platform.h>
#include <jansson.h>
#include <gnunet/gnunet_json_lib.h>
#include "taler_crypto_lib.h"
#include "taler_signatures.h"
@ -34,6 +35,11 @@ static char *masterkeyfile;
*/
static char *sepa_name;
/**
* Account holder address.
*/
static char *sepa_address;
/**
* IBAN number.
*/
@ -63,6 +69,9 @@ 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},
@ -88,6 +97,7 @@ main (int argc,
struct GNUNET_HashContext *hc;
json_t *reply;
char *json_str;
struct GNUNET_HashCode salt;
GNUNET_assert (GNUNET_OK ==
GNUNET_log_setup ("taler-exchange-sepa",
@ -112,8 +122,20 @@ main (int argc,
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,
@ -134,11 +156,15 @@ main (int argc,
GNUNET_free (eddsa_priv);
/* build JSON message */
reply = json_pack ("{s:s, s:s, s:s, s:o}",
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,
"sig", TALER_json_from_data (&sig,
"salt", GNUNET_JSON_from_data (&salt,
sizeof (salt)),
"sig", GNUNET_JSON_from_data (&sig,
sizeof (sig)));
GNUNET_assert (NULL != reply);

View File

@ -14,6 +14,7 @@ taler_exchange_aggregator_SOURCES = \
taler-exchange-aggregator.c
taler_exchange_aggregator_LDADD = \
$(LIBGCRYPT_LIBS) \
$(top_builddir)/src/json/libtalerjson.la \
$(top_builddir)/src/util/libtalerutil.la \
$(top_builddir)/src/wire/libtalerwire.la \
$(top_builddir)/src/exchangedb/libtalerexchangedb.la \
@ -36,11 +37,13 @@ taler_exchange_httpd_SOURCES = \
taler-exchange-httpd_validation.c taler-exchange-httpd_validation.h
taler_exchange_httpd_LDADD = \
$(LIBGCRYPT_LIBS) \
$(top_builddir)/src/json/libtalerjson.la \
$(top_builddir)/src/util/libtalerutil.la \
$(top_builddir)/src/exchangedb/libtalerexchangedb.la \
-lmicrohttpd \
-ljansson \
-lgnunetutil \
-lgnunetjson \
-ljansson \
-lpthread
if HAVE_DEVELOPER

View File

@ -29,6 +29,7 @@
#include <pthread.h>
#include "taler_exchangedb_lib.h"
#include "taler_exchangedb_plugin.h"
#include "taler_json_lib.h"
#include "taler_wire_lib.h"
/**
@ -277,7 +278,7 @@ deposit_cb (void *cls,
au->row_id = row_id;
au->wire = (json_t *) wire;
au->execution_time = GNUNET_TIME_absolute_get ();
TALER_hash_json (au->wire,
TALER_JSON_hash (au->wire,
&au->h_wire);
json_incref (au->wire);
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,

View File

@ -65,7 +65,7 @@ struct GNUNET_CONFIGURATION_Handle *cfg;
* Master public key (according to the
* configuration in the exchange directory).
*/
struct GNUNET_CRYPTO_EddsaPublicKey TMH_master_public_key;
struct TALER_MasterPublicKeyP TMH_master_public_key;
/**
* Our DB plugin.
@ -424,7 +424,7 @@ exchange_serve_process_config (const char *exchange_directory)
if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_public_key_from_string (TMH_master_public_key_str,
strlen (TMH_master_public_key_str),
&TMH_master_public_key))
&TMH_master_public_key.eddsa_pub))
{
fprintf (stderr,
"Invalid master public key given in exchange configuration.");

View File

@ -57,7 +57,7 @@ extern char *TMH_exchange_directory;
* Master public key (according to the
* configuration in the exchange directory).
*/
extern struct GNUNET_CRYPTO_EddsaPublicKey TMH_master_public_key;
extern struct TALER_MasterPublicKeyP TMH_master_public_key;
/**
* Private key of the exchange we use to sign messages.

View File

@ -21,6 +21,8 @@
#include "platform.h"
#include <pthread.h>
#include <jansson.h>
#include <gnunet/gnunet_json_lib.h>
#include "taler_json_lib.h"
#include "taler-exchange-httpd_responses.h"
#include "taler-exchange-httpd_keystate.h"
@ -1673,12 +1675,12 @@ handle_transaction_data (void *cls,
is also ugly if we ever add signatures over this data. (#4135) */
json_array_append (ctx->deposits,
json_pack ("{s:o, s:o, s:o, s:I, s:o}",
"deposit_value", TALER_json_from_amount (deposit_value),
"deposit_fee", TALER_json_from_amount (deposit_fee),
"H_contract", TALER_json_from_data (h_contract,
"deposit_value", TALER_JSON_from_amount (deposit_value),
"deposit_fee", TALER_JSON_from_amount (deposit_fee),
"H_contract", GNUNET_JSON_from_data (h_contract,
sizeof (struct GNUNET_HashCode)),
"transaction_id", (json_int_t) transaction_id,
"coin_pub", TALER_json_from_data (coin_pub,
"coin_pub", GNUNET_JSON_from_data (coin_pub,
sizeof (struct TALER_CoinSpendPublicKeyP))));
}

View File

@ -27,9 +27,11 @@
*/
#include "platform.h"
#include <gnunet/gnunet_util_lib.h>
#include <gnunet/gnunet_json_lib.h>
#include <jansson.h>
#include <microhttpd.h>
#include <pthread.h>
#include "taler_json_lib.h"
#include "taler-exchange-httpd_parsing.h"
#include "taler-exchange-httpd_deposit.h"
#include "taler-exchange-httpd_responses.h"
@ -170,7 +172,7 @@ parse_and_handle_deposit_request (struct MHD_Connection *connection,
"wire");
}
if (GNUNET_OK !=
TALER_hash_json (wire,
TALER_JSON_hash (wire,
&my_h_wire))
{
TALER_LOG_WARNING ("Failed to parse JSON wire format specification for /deposit request\n");

View File

@ -22,6 +22,7 @@
*/
#include "platform.h"
#include <pthread.h>
#include "taler_json_lib.h"
#include "taler-exchange-httpd_keystate.h"
#include "taler-exchange-httpd_responses.h"
#include "taler_exchangedb_plugin.h"
@ -144,26 +145,26 @@ denom_key_issue_to_json (const struct TALER_DenominationPublicKey *pk,
return
json_pack ("{s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:o}",
"master_sig",
TALER_json_from_data (&dki->signature,
GNUNET_JSON_from_data (&dki->signature,
sizeof (struct GNUNET_CRYPTO_EddsaSignature)),
"stamp_start",
TALER_json_from_abs (GNUNET_TIME_absolute_ntoh (dki->properties.start)),
GNUNET_JSON_from_time_abs (GNUNET_TIME_absolute_ntoh (dki->properties.start)),
"stamp_expire_withdraw",
TALER_json_from_abs (GNUNET_TIME_absolute_ntoh (dki->properties.expire_withdraw)),
GNUNET_JSON_from_time_abs (GNUNET_TIME_absolute_ntoh (dki->properties.expire_withdraw)),
"stamp_expire_deposit",
TALER_json_from_abs (GNUNET_TIME_absolute_ntoh (dki->properties.expire_spend)),
GNUNET_JSON_from_time_abs (GNUNET_TIME_absolute_ntoh (dki->properties.expire_spend)),
"stamp_expire_legal",
TALER_json_from_abs (GNUNET_TIME_absolute_ntoh (dki->properties.expire_legal)),
GNUNET_JSON_from_time_abs (GNUNET_TIME_absolute_ntoh (dki->properties.expire_legal)),
"denom_pub",
TALER_json_from_rsa_public_key (pk->rsa_public_key),
GNUNET_JSON_from_rsa_public_key (pk->rsa_public_key),
"value",
TALER_json_from_amount (&value),
TALER_JSON_from_amount (&value),
"fee_withdraw",
TALER_json_from_amount (&fee_withdraw),
TALER_JSON_from_amount (&fee_withdraw),
"fee_deposit",
TALER_json_from_amount (&fee_deposit),
TALER_JSON_from_amount (&fee_deposit),
"fee_refresh",
TALER_json_from_amount (&fee_refresh));
TALER_JSON_from_amount (&fee_refresh));
}
@ -342,19 +343,19 @@ sign_key_issue_to_json (const struct TALER_ExchangeSigningKeyValidityPS *ski)
return
json_pack ("{s:o, s:o, s:o, s:o, s:o, s:o}",
"stamp_start",
TALER_json_from_abs (GNUNET_TIME_absolute_ntoh (ski->start)),
GNUNET_JSON_from_time_abs (GNUNET_TIME_absolute_ntoh (ski->start)),
"stamp_expire",
TALER_json_from_abs (GNUNET_TIME_absolute_ntoh (ski->expire)),
GNUNET_JSON_from_time_abs (GNUNET_TIME_absolute_ntoh (ski->expire)),
"stamp_end",
TALER_json_from_abs (GNUNET_TIME_absolute_ntoh (ski->end)),
GNUNET_JSON_from_time_abs (GNUNET_TIME_absolute_ntoh (ski->end)),
"master_pub",
TALER_json_from_data (&ski->master_public_key,
GNUNET_JSON_from_data (&ski->master_public_key,
sizeof (struct TALER_MasterPublicKeyP)),
"master_sig",
TALER_json_from_data (&ski->signature,
GNUNET_JSON_from_data (&ski->signature,
sizeof (struct TALER_MasterSignatureP)),
"key",
TALER_json_from_data (&ski->signkey_pub,
GNUNET_JSON_from_data (&ski->signkey_pub,
sizeof (struct TALER_ExchangePublicKeyP)));
}
@ -437,16 +438,16 @@ auditor_to_json (const struct TALER_AuditorPublicKeyP *apub,
json_array_append_new (ja,
json_pack ("{s:o, s:o}",
"denom_pub_h",
TALER_json_from_data (&dki[i]->denom_hash,
GNUNET_JSON_from_data (&dki[i]->denom_hash,
sizeof (struct GNUNET_HashCode)),
"auditor_sig",
TALER_json_from_data (asigs[i],
GNUNET_JSON_from_data (asigs[i],
sizeof (struct TALER_AuditorSignatureP))));
return
json_pack ("{s:o, s:o}",
"denomination_keys", ja,
"auditor_pub",
TALER_json_from_data (apub,
GNUNET_JSON_from_data (apub,
sizeof (struct TALER_AuditorPublicKeyP)));
}
@ -633,7 +634,7 @@ TMH_KS_acquire_ (const char *location)
key_state->denomkey_map = GNUNET_CONTAINER_multihashmap_create (32,
GNUNET_NO);
key_state->reload_time = GNUNET_TIME_absolute_get ();
TALER_round_abs_time (&key_state->reload_time);
GNUNET_TIME_round_abs (&key_state->reload_time);
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Loading keys from `%s'\n",
TMH_exchange_directory);
@ -663,15 +664,15 @@ TMH_KS_acquire_ (const char *location)
keys = json_pack ("{s:o, s:o, s:o, s:o, s:o, s:o, s:o}",
"master_public_key",
TALER_json_from_data (&TMH_master_public_key,
GNUNET_JSON_from_data (&TMH_master_public_key,
sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)),
"signkeys", key_state->sign_keys_array,
"denoms", key_state->denom_keys_array,
"auditors", key_state->auditors_array,
"list_issue_date", TALER_json_from_abs (key_state->reload_time),
"eddsa_pub", TALER_json_from_data (&key_state->current_sign_key_issue.issue.signkey_pub,
"list_issue_date", GNUNET_JSON_from_time_abs (key_state->reload_time),
"eddsa_pub", GNUNET_JSON_from_data (&key_state->current_sign_key_issue.issue.signkey_pub,
sizeof (struct TALER_ExchangePublicKeyP)),
"eddsa_sig", TALER_json_from_data (&sig,
"eddsa_sig", GNUNET_JSON_from_data (&sig,
sizeof (struct TALER_ExchangeSignatureP)));
key_state->auditors_array = NULL;
key_state->sign_keys_array = NULL;

View File

@ -24,6 +24,7 @@
#include "platform.h"
#include <gnunet/gnunet_util_lib.h>
#include "taler_json_lib.h"
#include "taler-exchange-httpd_parsing.h"
#include "taler-exchange-httpd_responses.h"
@ -786,10 +787,15 @@ TMH_PARSE_navigate_json (struct MHD_Connection *connection,
case TMH_PARSE_JNC_RET_AMOUNT:
{
struct TALER_Amount *where = va_arg (argp, void *);
struct GNUNET_JSON_Specification spec[] = {
TALER_JSON_spec_amount (NULL, where),
GNUNET_JSON_spec_end ()
};
if (GNUNET_OK !=
TALER_json_to_amount ((json_t *) root,
where))
GNUNET_JSON_parse ((json_t *) root,
spec,
NULL, NULL))
{
GNUNET_break_op (0);
ret = (MHD_YES !=
@ -823,10 +829,15 @@ TMH_PARSE_navigate_json (struct MHD_Connection *connection,
case TMH_PARSE_JNC_RET_TIME_ABSOLUTE:
{
struct GNUNET_TIME_Absolute *where = va_arg (argp, void *);
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_absolute_time (NULL, where),
GNUNET_JSON_spec_end ()
};
if (GNUNET_OK !=
TALER_json_to_abs ((json_t *) root,
where))
GNUNET_JSON_parse ((json_t *) root,
spec,
NULL, NULL))
{
GNUNET_break_op (0);
ret = (MHD_YES !=

View File

@ -25,7 +25,7 @@
#include "platform.h"
#include "taler-exchange-httpd_responses.h"
#include "taler_util.h"
#include <gnunet/gnunet_util_lib.h>
#include "taler_json_lib.h"
#include "taler-exchange-httpd_keystate.h"
@ -388,9 +388,9 @@ TMH_RESPONSE_reply_deposit_success (struct MHD_Connection *connection,
MHD_HTTP_OK,
"{s:s, s:o, s:o}",
"status", "DEPOSIT_OK",
"sig", TALER_json_from_data (&sig,
"sig", GNUNET_JSON_from_data (&sig,
sizeof (sig)),
"pub", TALER_json_from_data (&pub,
"pub", GNUNET_JSON_from_data (&pub,
sizeof (pub)));
}
@ -449,7 +449,7 @@ compile_transaction_history (const struct TALER_EXCHANGEDB_TransactionList *tl)
return NULL;
}
details = TALER_json_from_data (&dr.purpose,
details = GNUNET_JSON_from_data (&dr.purpose,
sizeof (struct TALER_DepositRequestPS));
break;
}
@ -481,7 +481,7 @@ compile_transaction_history (const struct TALER_EXCHANGEDB_TransactionList *tl)
return NULL;
}
details = TALER_json_from_data (&ms.purpose,
details = GNUNET_JSON_from_data (&ms.purpose,
sizeof (struct TALER_RefreshMeltCoinAffirmationPS));
}
break;
@ -491,8 +491,8 @@ compile_transaction_history (const struct TALER_EXCHANGEDB_TransactionList *tl)
json_array_append_new (history,
json_pack ("{s:s, s:o, s:o, s:o}",
"type", type,
"amount", TALER_json_from_amount (&value),
"signature", TALER_json_from_data (sig,
"amount", TALER_JSON_from_amount (&value),
"signature", GNUNET_JSON_from_data (sig,
sizeof (struct TALER_CoinSpendSignatureP)),
"details", details));
}
@ -569,7 +569,7 @@ compile_reserve_history (const struct TALER_EXCHANGEDB_ReserveHistory *rh,
json_pack ("{s:s, s:O, s:o}",
"type", "DEPOSIT",
"wire", pos->details.bank->wire,
"amount", TALER_json_from_amount (&pos->details.bank->amount)));
"amount", TALER_JSON_from_amount (&pos->details.bank->amount)));
break;
case TALER_EXCHANGEDB_RO_WITHDRAW_COIN:
break;
@ -614,11 +614,11 @@ compile_reserve_history (const struct TALER_EXCHANGEDB_ReserveHistory *rh,
json_array_append_new (json_history,
json_pack ("{s:s, s:o, s:o, s:o}",
"type", "WITHDRAW",
"signature", TALER_json_from_data (&pos->details.withdraw->reserve_sig,
"signature", GNUNET_JSON_from_data (&pos->details.withdraw->reserve_sig,
sizeof (struct TALER_ReserveSignatureP)),
"details", TALER_json_from_data (&wr,
"details", GNUNET_JSON_from_data (&wr,
sizeof (wr)),
"amount", TALER_json_from_amount (&value)));
"amount", TALER_JSON_from_amount (&value)));
break;
}
}
@ -662,7 +662,7 @@ TMH_RESPONSE_reply_reserve_status_success (struct MHD_Connection *connection,
if (NULL == json_history)
return TMH_RESPONSE_reply_internal_error (connection,
"balance calculation failure");
json_balance = TALER_json_from_amount (&balance);
json_balance = TALER_JSON_from_amount (&balance);
return TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_OK,
"{s:o, s:o}",
@ -693,7 +693,7 @@ TMH_RESPONSE_reply_reserve_withdraw_insufficient_funds (struct MHD_Connection *c
if (NULL == json_history)
return TMH_RESPONSE_reply_internal_error (connection,
"balance calculation failure");
json_balance = TALER_json_from_amount (&balance);
json_balance = TALER_JSON_from_amount (&balance);
return TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_PAYMENT_REQUIRED,
"{s:s, s:o, s:o}",
@ -716,7 +716,7 @@ TMH_RESPONSE_reply_reserve_withdraw_success (struct MHD_Connection *connection,
{
json_t *sig_json;
sig_json = TALER_json_from_rsa_signature (collectable->sig.rsa_signature);
sig_json = GNUNET_JSON_from_rsa_signature (collectable->sig.rsa_signature);
return TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_OK,
"{s:o}",
@ -758,14 +758,14 @@ TMH_RESPONSE_reply_refresh_melt_insufficient_funds (struct MHD_Connection *conne
"error",
"insufficient funds",
"coin_pub",
TALER_json_from_data (coin_pub,
GNUNET_JSON_from_data (coin_pub,
sizeof (struct TALER_CoinSpendPublicKeyP)),
"original_value",
TALER_json_from_amount (&coin_value),
TALER_JSON_from_amount (&coin_value),
"residual_value",
TALER_json_from_amount (&residual),
TALER_JSON_from_amount (&residual),
"requested_value",
TALER_json_from_amount (&requested),
TALER_JSON_from_amount (&requested),
"history",
history);
}
@ -797,7 +797,7 @@ TMH_RESPONSE_reply_refresh_melt_success (struct MHD_Connection *connection,
TMH_KS_sign (&body.purpose,
&pub,
&sig);
sig_json = TALER_json_from_data (&sig,
sig_json = GNUNET_JSON_from_data (&sig,
sizeof (sig));
GNUNET_assert (NULL != sig_json);
return TMH_RESPONSE_reply_json_pack (connection,
@ -805,7 +805,7 @@ TMH_RESPONSE_reply_refresh_melt_success (struct MHD_Connection *connection,
"{s:i, s:o, s:o}",
"noreveal_index", (int) noreveal_index,
"exchange_sig", sig_json,
"exchange_pub", TALER_json_from_data (&pub,
"exchange_pub", GNUNET_JSON_from_data (&pub,
sizeof (pub)));
}
@ -835,7 +835,7 @@ TMH_RESPONSE_reply_refresh_reveal_success (struct MHD_Connection *connection,
obj = json_object ();
json_object_set_new (obj,
"ev_sig",
TALER_json_from_rsa_signature (sigs[newcoin_index].rsa_signature));
GNUNET_JSON_from_rsa_signature (sigs[newcoin_index].rsa_signature));
json_array_append_new (list,
obj);
}
@ -889,18 +889,18 @@ TMH_RESPONSE_reply_refresh_reveal_missmatch (struct MHD_Connection *connection,
rm_json = json_object ();
json_object_set_new (rm_json,
"coin_sig",
TALER_json_from_data (&rm->coin_sig,
GNUNET_JSON_from_data (&rm->coin_sig,
sizeof (struct TALER_CoinSpendSignatureP)));
json_object_set_new (rm_json,
"coin_pub",
TALER_json_from_data (&rm->coin.coin_pub,
GNUNET_JSON_from_data (&rm->coin.coin_pub,
sizeof (struct TALER_CoinSpendPublicKeyP)));
json_object_set_new (rm_json,
"melt_amount_with_fee",
TALER_json_from_amount (&rm->amount_with_fee));
TALER_JSON_from_amount (&rm->amount_with_fee));
json_object_set_new (rm_json,
"melt_fee",
TALER_json_from_amount (&rm->melt_fee));
TALER_JSON_from_amount (&rm->melt_fee));
json_array_append_new (info_old,
rm_json);
}
@ -911,7 +911,7 @@ TMH_RESPONSE_reply_refresh_reveal_missmatch (struct MHD_Connection *connection,
pk = &mc->denom_pubs[i];
json_array_append_new (info_new,
TALER_json_from_rsa_public_key (pk->rsa_public_key));
GNUNET_JSON_from_rsa_public_key (pk->rsa_public_key));
}
info_commit = json_array ();
@ -931,15 +931,15 @@ TMH_RESPONSE_reply_refresh_reveal_missmatch (struct MHD_Connection *connection,
cc_json = json_object ();
json_object_set_new (cc_json,
"coin_ev",
TALER_json_from_data (cc->coin_ev,
GNUNET_JSON_from_data (cc->coin_ev,
cc->coin_ev_size));
json_object_set_new (cc_json,
"coin_priv_enc",
TALER_json_from_data (cc->refresh_link->coin_priv_enc,
GNUNET_JSON_from_data (cc->refresh_link->coin_priv_enc,
sizeof (struct TALER_CoinSpendPrivateKeyP)));
json_object_set_new (cc_json,
"blinding_key_enc",
TALER_json_from_data (cc->refresh_link->blinding_key_enc,
GNUNET_JSON_from_data (cc->refresh_link->blinding_key_enc,
cc->refresh_link->blinding_key_enc_size));
json_array_append_new (info_commit_k,
@ -957,11 +957,11 @@ TMH_RESPONSE_reply_refresh_reveal_missmatch (struct MHD_Connection *connection,
cl_json = json_object ();
json_object_set_new (cl_json,
"transfer_pub",
TALER_json_from_data (&cl->transfer_pub,
GNUNET_JSON_from_data (&cl->transfer_pub,
sizeof (struct TALER_TransferPublicKeyP)));
json_object_set_new (cl_json,
"shared_secret_enc",
TALER_json_from_data (&cl->shared_secret_enc,
GNUNET_JSON_from_data (&cl->shared_secret_enc,
sizeof (struct TALER_EncryptedLinkSecretP)));
json_array_append_new (info_link_k,
cl_json);
@ -1015,15 +1015,15 @@ TMH_RESPONSE_reply_refresh_link_success (struct MHD_Connection *connection,
obj = json_object ();
json_object_set_new (obj,
"link_enc",
TALER_json_from_data (pos->link_data_enc->coin_priv_enc,
GNUNET_JSON_from_data (pos->link_data_enc->coin_priv_enc,
sizeof (struct TALER_CoinSpendPrivateKeyP) +
pos->link_data_enc->blinding_key_enc_size));
json_object_set_new (obj,
"denom_pub",
TALER_json_from_rsa_public_key (pos->denom_pub.rsa_public_key));
GNUNET_JSON_from_rsa_public_key (pos->denom_pub.rsa_public_key));
json_object_set_new (obj,
"ev_sig",
TALER_json_from_rsa_signature (pos->ev_sig.rsa_signature));
GNUNET_JSON_from_rsa_signature (pos->ev_sig.rsa_signature));
json_array_append_new (list,
obj);
}
@ -1033,11 +1033,11 @@ TMH_RESPONSE_reply_refresh_link_success (struct MHD_Connection *connection,
list);
json_object_set_new (root,
"transfer_pub",
TALER_json_from_data (&sessions[i].transfer_pub,
GNUNET_JSON_from_data (&sessions[i].transfer_pub,
sizeof (struct TALER_TransferPublicKeyP)));
json_object_set_new (root,
"secret_enc",
TALER_json_from_data (&sessions[i].shared_secret_enc,
GNUNET_JSON_from_data (&sessions[i].shared_secret_enc,
sizeof (struct TALER_EncryptedLinkSecretP)));
json_array_append_new (mlist,
root);
@ -1083,7 +1083,7 @@ TMH_RESPONSE_reply_deposit_pending (struct MHD_Connection *connection,
return TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_ACCEPTED,
"{s:o}",
"execution_time", TALER_json_from_abs (planned_exec_time));
"execution_time", GNUNET_JSON_from_time_abs (planned_exec_time));
}
@ -1132,13 +1132,13 @@ TMH_RESPONSE_reply_deposit_wtid (struct MHD_Connection *connection,
return TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_OK,
"{s:o, s:o, s:o, s:o, s:o, s:o}",
"wtid", TALER_json_from_data (wtid,
"wtid", GNUNET_JSON_from_data (wtid,
sizeof (*wtid)),
"execution_time", TALER_json_from_abs (exec_time),
"coin_contribution", TALER_json_from_amount (coin_contribution),
"exchange_sig", TALER_json_from_data (&sig,
"execution_time", GNUNET_JSON_from_time_abs (exec_time),
"coin_contribution", TALER_JSON_from_amount (coin_contribution),
"exchange_sig", GNUNET_JSON_from_data (&sig,
sizeof (sig)),
"exchange_pub", TALER_json_from_data (&pub,
"exchange_pub", GNUNET_JSON_from_data (&pub,
sizeof (pub)));
}
@ -1165,10 +1165,10 @@ TMH_RESPONSE_reply_wire_deposit_details (struct MHD_Connection *connection,
return TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_OK,
"{s:o, s:o, s:o, s:o}",
"total", TALER_json_from_amount (total),
"merchant_pub", TALER_json_from_data (merchant_pub,
"total", TALER_JSON_from_amount (total),
"merchant_pub", GNUNET_JSON_from_data (merchant_pub,
sizeof (struct TALER_MerchantPublicKeyP)),
"h_wire", TALER_json_from_data (h_wire,
"h_wire", GNUNET_JSON_from_data (h_wire,
sizeof (struct GNUNET_HashCode)),
"deposits", deposits);
}

View File

@ -21,6 +21,7 @@
*/
#include "platform.h"
#include <gnunet/gnunet_util_lib.h>
#include <gnunet/gnunet_json_lib.h>
#include <jansson.h>
#include <microhttpd.h>
#include "taler_signatures.h"
@ -90,7 +91,7 @@ TMH_TEST_handler_test_base32 (struct TMH_RequestHandler *rh,
MHD_HTTP_OK,
"{s:o}",
"output",
TALER_json_from_data (&hc, sizeof (struct GNUNET_HashCode)));
GNUNET_JSON_from_data (&hc, sizeof (struct GNUNET_HashCode)));
}
@ -164,7 +165,7 @@ TMH_TEST_handler_test_encrypt (struct TMH_RequestHandler *rh,
&skey,
&iv,
out));
json = TALER_json_from_data (out,
json = GNUNET_JSON_from_data (out,
in_ptr_size);
GNUNET_free (out);
TMH_PARSE_release_data (spec);
@ -231,7 +232,7 @@ TMH_TEST_handler_test_hkdf (struct TMH_RequestHandler *rh,
in_ptr_size,
NULL, 0);
TMH_PARSE_release_data (spec);
json = TALER_json_from_data (&hc,
json = GNUNET_JSON_from_data (&hc,
sizeof (struct GNUNET_HashCode));
return TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_OK,
@ -302,7 +303,7 @@ TMH_TEST_handler_test_ecdhe (struct TMH_RequestHandler *rh,
MHD_HTTP_OK,
"{s:o}",
"ecdh_hash",
TALER_json_from_data (&hc,
GNUNET_JSON_from_data (&hc,
sizeof (hc)));
}
@ -387,10 +388,10 @@ TMH_TEST_handler_test_eddsa (struct TMH_RequestHandler *rh,
MHD_HTTP_OK,
"{s:o, s:o}",
"eddsa_pub",
TALER_json_from_data (&pub,
GNUNET_JSON_from_data (&pub,
sizeof (pub)),
"eddsa_sig",
TALER_json_from_data (&sig,
GNUNET_JSON_from_data (&sig,
sizeof (sig)));
}
@ -435,7 +436,7 @@ TMH_TEST_handler_test_rsa_get (struct TMH_RequestHandler *rh,
MHD_HTTP_OK,
"{s:o}",
"rsa_pub",
TALER_json_from_rsa_public_key (pub));
GNUNET_JSON_from_rsa_public_key (pub));
GNUNET_CRYPTO_rsa_public_key_free (pub);
return res;
}
@ -509,7 +510,7 @@ TMH_TEST_handler_test_rsa_sign (struct TMH_RequestHandler *rh,
MHD_HTTP_OK,
"{s:o}",
"rsa_blind_sig",
TALER_json_from_rsa_signature (sig));
GNUNET_JSON_from_rsa_signature (sig));
GNUNET_CRYPTO_rsa_signature_free (sig);
return res;
}
@ -578,7 +579,7 @@ TMH_TEST_handler_test_transfer (struct TMH_RequestHandler *rh,
MHD_HTTP_OK,
"{s:o}",
"secret",
TALER_json_from_data (&secret,
GNUNET_JSON_from_data (&secret,
sizeof (secret)));
}

View File

@ -21,6 +21,7 @@
*/
#include "platform.h"
#include <gnunet/gnunet_util_lib.h>
#include "taler-exchange-httpd.h"
#include "taler-exchange-httpd_validation.h"
#include "taler_wire_plugin.h"
@ -172,7 +173,9 @@ TMH_json_validate_wireformat (const json_t *wire)
for (p=wire_head; NULL != p; p = p->next)
if (0 == strcasecmp (p->type,
stype))
return p->plugin->wire_validate (wire);
return p->plugin->wire_validate (p->plugin->cls,
wire,
&TMH_master_public_key);
return GNUNET_NO;
}

View File

@ -19,6 +19,7 @@
* @author Christian Grothoff
*/
#include "platform.h"
#include <gnunet/gnunet_json_lib.h>
#include "taler-exchange-httpd_keystate.h"
#include "taler-exchange-httpd_responses.h"
#include "taler-exchange-httpd_validation.h"
@ -57,9 +58,9 @@ TMH_WIRE_handler_wire (struct TMH_RequestHandler *rh,
MHD_HTTP_OK,
"{s:o, s:o, s:o}",
"methods", methods,
"sig", TALER_json_from_data (&sig,
"sig", GNUNET_JSON_from_data (&sig,
sizeof (sig)),
"pub", TALER_json_from_data (&pub,
"pub", GNUNET_JSON_from_data (&pub,
sizeof (pub)));
}

View File

@ -22,6 +22,7 @@
#ifndef _TALER_EXCHANGE_SERVICE_H
#define _TALER_EXCHANGE_SERVICE_H
#include <jansson.h>
#include "taler_util.h"
/* ********************* event loop *********************** */

View File

@ -22,6 +22,7 @@
#ifndef TALER_EXCHANGEDB_PLUGIN_H
#define TALER_EXCHANGEDB_PLUGIN_H
#include <jansson.h>
#include <gnunet/gnunet_util_lib.h>
#include "taler_exchangedb_lib.h"

View File

@ -1,6 +1,6 @@
/*
This file is part of TALER
Copyright (C) 2014, 2015 GNUnet e.V.
Copyright (C) 2014, 2015, 2016 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
@ -17,14 +17,18 @@
* @file include/taler_json_lib.h
* @brief helper functions for JSON processing using libjansson
* @author Sree Harsha Totakura <sreeharsha@totakura.in>
* @author Christian Grothoff
*/
#ifndef TALER_json_LIB_H_
#define TALER_json_LIB_H_
#ifndef TALER_JSON_LIB_H_
#define TALER_JSON_LIB_H_
#include <jansson.h>
#include <gnunet/gnunet_json_lib.h>
#include "taler_util.h"
/**
* Print JSON parsing related error information
* @deprecated
*/
#define TALER_json_warn(error) \
GNUNET_log (GNUNET_ERROR_TYPE_WARNING, \
@ -39,107 +43,19 @@
* @return a json object describing the amount
*/
json_t *
TALER_json_from_amount (const struct TALER_Amount *amount);
TALER_JSON_from_amount (const struct TALER_Amount *amount);
/**
* Convert absolute timestamp to a json string.
* Provide specification to parse given JSON object to an amount.
*
* @param stamp the time stamp
* @return a json string with the timestamp in @a stamp
*/
json_t *
TALER_json_from_abs (struct GNUNET_TIME_Absolute stamp);
/**
* Convert RSA public key to JSON.
*
* @param pk public key to convert
* @return corresponding JSON encoding
*/
json_t *
TALER_json_from_rsa_public_key (struct GNUNET_CRYPTO_rsa_PublicKey *pk);
/**
* Convert RSA signature to JSON.
*
* @param sig signature to convert
* @return corresponding JSON encoding
*/
json_t *
TALER_json_from_rsa_signature (struct GNUNET_CRYPTO_rsa_Signature *sig);
/**
* Convert binary data to a JSON string
* with the base32crockford encoding.
*
* @param data binary data
* @param size size of @a data in bytes
* @return json string that encodes @a data
*/
json_t *
TALER_json_from_data (const void *data,
size_t size);
/**
* Parse given JSON object to Amount
*
* @param json the json object representing Amount
* @param name name of the amount field in the JSON
* @param[out] r_amount where the amount has to be written
* @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
*/
int
TALER_json_to_amount (json_t *json,
struct GNUNET_JSON_Specification
TALER_JSON_spec_amount (const char *name,
struct TALER_Amount *r_amount);
/**
* Parse given JSON object to absolute time.
*
* @param json the json object representing absolute time in seconds
* @param[out] abs where the time has to be written
* @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
*/
int
TALER_json_to_abs (json_t *json,
struct GNUNET_TIME_Absolute *abs);
/**
* Parse given JSON object to data
*
* @param json the json object representing data
* @param out the pointer to hold the parsed data.
* @param out_size the size of @a out
* @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
*/
int
TALER_json_to_data (json_t *json,
void *out,
size_t out_size);
/**
* Convert JSON to RSA public key.
*
* @param json JSON encoding to convert
* @return corresponding public key
*/
struct GNUNET_CRYPTO_rsa_PublicKey *
TALER_json_to_rsa_public_key (json_t *json);
/**
* Convert JSON to RSA signature.
*
* @param json JSON encoding to convert
* @return corresponding signature
*/
struct GNUNET_CRYPTO_rsa_Signature *
TALER_json_to_rsa_signature (json_t *json);
/**
* Hash a JSON for binary signing.
@ -149,22 +65,9 @@ TALER_json_to_rsa_signature (json_t *json);
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
*/
int
TALER_hash_json (json_t *json,
TALER_JSON_hash (json_t *json,
struct GNUNET_HashCode *hc);
/**
* Check if the given wire format JSON object is correctly formatted
*
* @param allowed NULL-terminated array of allowed wire format types
* @param wire the JSON wire format object
* @return #GNUNET_YES if correctly formatted; #GNUNET_NO if not
*/
int
TALER_json_validate_wireformat (const char **allowed,
const json_t *wire);
#endif /* TALER_json_LIB_H_ */
#endif /* TALER_JSON_LIB_H_ */
/* End of taler_json_lib.h */

View File

@ -24,6 +24,7 @@
#define TALER_PQ_LIB_H_
#include <libpq-fe.h>
#include <jansson.h>
#include <gnunet/gnunet_pq_lib.h>
#include "taler_util.h"

View File

@ -24,8 +24,6 @@
#include <gnunet/gnunet_util_lib.h>
#include "taler_amount_lib.h"
#include "taler_crypto_lib.h"
#include "taler_json_lib.h"
/* Define logging functions */
@ -97,30 +95,6 @@ TALER_b2s (const void *buf,
#define TALER_B2S(obj) TALER_b2s (obj, sizeof (*obj))
/**
* Round a time value so that it is suitable for transmission
* via JSON encodings.
*
* @param at time to round
* @return #GNUNET_OK if time was already rounded, #GNUNET_NO if
* it was just now rounded
*/
int
TALER_round_abs_time (struct GNUNET_TIME_Absolute *at);
/**
* Round a time value so that it is suitable for transmission
* via JSON encodings.
*
* @param rt time to round
* @return #GNUNET_OK if time was already rounded, #GNUNET_NO if
* it was just now rounded
*/
int
TALER_round_rel_time (struct GNUNET_TIME_Relative *rt);
/**
* Load configuration by parsing all configuration
* files in the given directory.

View File

@ -101,11 +101,15 @@ struct TALER_WIRE_Plugin
/**
* Check if the given wire format JSON object is correctly formatted
*
* @param cls the @e cls of this struct with the plugin-specific state
* @param wire the JSON wire format object
* @param master_pub public key of the exchange to verify against
* @return #GNUNET_YES if correctly formatted; #GNUNET_NO if not
*/
int
(*wire_validate) (const json_t *wire);
(*wire_validate) (void *cls,
const json_t *wire,
const struct TALER_MasterPublicKeyP *master_pub);
/**

38
src/json/Makefile.am Normal file
View File

@ -0,0 +1,38 @@
# This Makefile.am is in the public domain
AM_CPPFLAGS = -I$(top_srcdir)/src/include
if USE_COVERAGE
AM_CFLAGS = --coverage -O0
XLIB = -lgcov
endif
lib_LTLIBRARIES = \
libtalerjson.la
libtalerjson_la_SOURCES = \
json.c \
json_helper.c
libtalerjson_la_LDFLAGS = \
-version-info 0:0:0 \
-export-dynamic -no-undefined
libtalerjson_la_LIBADD = \
-lgnunetjson \
$(top_builddir)/src/util/libtalerutil.la \
-lgnunetutil \
-ljansson \
$(XLIB)
TESTS = \
test_json
check_PROGRAMS= \
test_json
test_json_SOURCES = \
test_json.c
test_json_LDADD = \
-ltalerjson \
-lgnunetjson \
$(top_builddir)/src/util/libtalerutil.la \
-lgnunetutil \
-ljansson

53
src/json/json.c Normal file
View File

@ -0,0 +1,53 @@
/*
This file is part of TALER
Copyright (C) 2014, 2015, 2016 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 json/json.c
* @brief helper functions for JSON processing using libjansson
* @author Sree Harsha Totakura <sreeharsha@totakura.in>
*/
#include "platform.h"
#include <gnunet/gnunet_util_lib.h>
#include "taler_util.h"
#include "taler_json_lib.h"
/**
* Hash a JSON for binary signing.
*
* @param[in] json some JSON value
* @param[out] hc resulting hash code
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
*/
int
TALER_JSON_hash (json_t *json,
struct GNUNET_HashCode *hc)
{
char *wire_enc;
size_t len;
if (NULL == (wire_enc = json_dumps (json,
JSON_COMPACT | JSON_SORT_KEYS)))
return GNUNET_SYSERR;
len = strlen (wire_enc) + 1;
GNUNET_CRYPTO_hash (wire_enc,
len,
hc);
free (wire_enc);
return GNUNET_OK;
}
/* End of json/json.c */

146
src/json/json_helper.c Normal file
View File

@ -0,0 +1,146 @@
/*
This file is part of TALER
Copyright (C) 2014, 2015, 2016 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 json/json_helper.c
* @brief helper functions to generate specifications to parse
* Taler-specific JSON objects with libgnunetjson
* @author Sree Harsha Totakura <sreeharsha@totakura.in>
* @author Christian Grothoff
*/
#include "platform.h"
#include <gnunet/gnunet_util_lib.h>
#include "taler_util.h"
#include "taler_json_lib.h"
/**
* Convert a TALER amount to a JSON object.
*
* @param amount the amount
* @return a json object describing the amount
*/
json_t *
TALER_JSON_from_amount (const struct TALER_Amount *amount)
{
json_t *j;
if ( (amount->value != (uint64_t) ((json_int_t) amount->value)) ||
(0 > ((json_int_t) amount->value)) )
{
/* Theoretically, json_int_t can be a 32-bit "long", or we might
have a 64-bit value which converted to a 63-bit signed long
long causes problems here. So we check. Note that depending
on the platform, the compiler may be able to statically tell
that at least the first check is always false. */
GNUNET_break (0);
return NULL;
}
j = json_pack ("{s:s, s:I, s:I}",
"currency", amount->currency,
"value", (json_int_t) amount->value,
"fraction", (json_int_t) amount->fraction);
GNUNET_assert (NULL != j);
return j;
}
/**
* Parse given JSON object to Amount
*
* @param cls closure, NULL
* @param root the json object representing data
* @param[out] spec where to write the data
* @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
*/
static int
parse_amount (void *cls,
json_t *root,
struct GNUNET_JSON_Specification *spec)
{
struct TALER_Amount *r_amount = spec->ptr;
json_int_t value;
json_int_t fraction;
const char *currency;
memset (r_amount,
0,
sizeof (struct TALER_Amount));
if (0 != json_unpack (root,
"{s:I, s:I, s:s}",
"value", &value,
"fraction", &fraction,
"currency", &currency))
{
char *json_enc;
if (NULL == (json_enc = json_dumps (root,
JSON_COMPACT | JSON_ENCODE_ANY)))
{
GNUNET_break (0);
return GNUNET_SYSERR;
}
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Malformed JSON amount: %s\n",
json_enc);
free (json_enc);
return GNUNET_SYSERR;
}
if ( (value < 0) ||
(fraction < 0) ||
(value > UINT64_MAX) ||
(fraction > UINT32_MAX) )
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
if (strlen (currency) >= TALER_CURRENCY_LEN)
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
r_amount->value = (uint64_t) value;
r_amount->fraction = (uint32_t) fraction;
strcpy (r_amount->currency, currency);
(void) TALER_amount_normalize (r_amount);
return GNUNET_OK;
}
/**
* Provide specification to parse given JSON object to an amount.
*
* @param name name of the amount field in the JSON
* @param[out] r_amount where the amount has to be written
*/
struct GNUNET_JSON_Specification
TALER_JSON_spec_amount (const char *name,
struct TALER_Amount *r_amount)
{
struct GNUNET_JSON_Specification ret = {
.parser = &parse_amount,
.cleaner = NULL,
.cls = NULL,
.field = name,
.ptr = r_amount,
.ptr_size = 0,
.size_ptr = NULL
};
return ret;
}
/* end of json/json_helper.c */

71
src/json/test_json.c Normal file
View File

@ -0,0 +1,71 @@
/*
This file is part of TALER
(C) 2015, 2016 GNUnet e.V. and 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 json/test_json.c
* @brief Tests for Taler-specific crypto logic
* @author Christian Grothoff <christian@grothoff.org>
*/
#include "platform.h"
#include "taler_util.h"
#include "taler_json_lib.h"
/**
* Test amount conversion from/to JSON.
*
* @return 0 on success
*/
static int
test_amount ()
{
json_t *j;
struct TALER_Amount a1;
struct TALER_Amount a2;
struct GNUNET_JSON_Specification spec[] = {
TALER_JSON_spec_amount (NULL, &a2),
GNUNET_JSON_spec_end()
};
GNUNET_assert (GNUNET_OK ==
TALER_string_to_amount ("EUR:4.3",
&a1));
j = TALER_JSON_from_amount (&a1);
GNUNET_assert (NULL != j);
GNUNET_assert (GNUNET_OK ==
GNUNET_JSON_parse (j, spec,
NULL, NULL));
GNUNET_assert (0 ==
TALER_amount_cmp (&a1,
&a2));
json_decref (j);
return 0;
}
int
main(int argc,
const char *const argv[])
{
GNUNET_log_setup ("test-json",
"WARNING",
NULL);
if (0 != test_amount ())
return 1;
return 0;
}
/* end of test_json.c */

View File

@ -320,10 +320,11 @@ extract_json (void *cls,
&json_error);
if (NULL == *j_dst)
{
TALER_json_warn (json_error);
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failed to parse JSON result for field `%s'\n",
fname);
"Failed to parse JSON result for field `%s': %s (%s)\n",
fname,
json_error.text,
json_error.source);
return GNUNET_SYSERR;
}
return GNUNET_OK;

View File

@ -1,5 +1,5 @@
# This Makefile.am is in the public domain
AM_CPPFLAGS = -I$(top_srcdir)/src/include $(LIBGCRYPT_CFLAGS) $(POSTGRESQL_CPPFLAGS)
AM_CPPFLAGS = -I$(top_srcdir)/src/include $(LIBGCRYPT_CFLAGS)
if USE_COVERAGE
AM_CFLAGS = --coverage -O0
@ -31,15 +31,12 @@ libtalerutil_la_SOURCES = \
amount.c \
crypto.c \
util.c \
json.c \
os_installation.c \
plugin.c \
wireformats.c
plugin.c
libtalerutil_la_LIBADD = \
-lgnunetutil \
$(LIBGCRYPT_LIBS) \
-ljansson \
-lmicrohttpd $(XLIB)
libtalerutil_la_LDFLAGS = \
@ -48,13 +45,11 @@ libtalerutil_la_LDFLAGS = \
TESTS = \
test_amount \
test_crypto \
test_json
test_crypto
check_PROGRAMS= \
test_amount \
test_crypto \
test_json
test_crypto
test_amount_SOURCES = \
@ -68,10 +63,3 @@ test_crypto_SOURCES = \
test_crypto_LDADD = \
-lgnunetutil \
libtalerutil.la
test_json_SOURCES = \
test_json.c
test_json_LDADD = \
-lgnunetutil \
-ljansson \
libtalerutil.la

View File

@ -1,400 +0,0 @@
/*
This file is part of TALER
Copyright (C) 2014, 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 util/json.c
* @brief helper functions for JSON processing using libjansson
* @author Sree Harsha Totakura <sreeharsha@totakura.in>
*/
#include "platform.h"
#if HAVE_GNUNET_GNUNET_UTIL_TALER_WALLET_LIB_H
#include <gnunet/gnunet_util_taler_wallet_lib.h>
#endif
#if HAVE_GNUNET_GNUNET_UTIL_LIB_H
#include <gnunet/gnunet_util_lib.h>
#endif
#include "taler_util.h"
/**
* Shorthand for exit jumps.
*/
#define EXITIF(cond) \
do { \
if (cond) { GNUNET_break (0); goto EXITIF_exit; } \
} while (0)
/**
* Shorthand for JSON parsing related exit jumps.
*/
#define UNPACK_EXITIF(cond) \
do { \
if (cond) { TALER_json_warn (error); goto EXITIF_exit; } \
} while (0)
/**
* Convert a TALER amount to a JSON
* object.
*
* @param amount the amount
* @return a json object describing the amount
*/
json_t *
TALER_json_from_amount (const struct TALER_Amount *amount)
{
json_t *j;
if ( (amount->value != (uint64_t) ((json_int_t) amount->value)) ||
(0 > ((json_int_t) amount->value)) )
{
/* Theoretically, json_int_t can be a 32-bit "long", or we might
have a 64-bit value which converted to a 63-bit signed long
long causes problems here. So we check. Note that depending
on the platform, the compiler may be able to statically tell
that at least the first check is always false. */
GNUNET_break (0);
return NULL;
}
j = json_pack ("{s:s, s:I, s:I}",
"currency", amount->currency,
"value", (json_int_t) amount->value,
"fraction", (json_int_t) amount->fraction);
GNUNET_assert (NULL != j);
return j;
}
/**
* Convert absolute timestamp to a json string.
*
* @param stamp the time stamp
* @return a json string with the timestamp in @a stamp
*/
json_t *
TALER_json_from_abs (struct GNUNET_TIME_Absolute stamp)
{
json_t *j;
char *mystr;
int ret;
GNUNET_assert (GNUNET_OK ==
TALER_round_abs_time (&stamp));
if (stamp.abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us)
return json_string ("/never/");
ret = GNUNET_asprintf (&mystr,
"/Date(%llu)/",
(unsigned long long) (stamp.abs_value_us / (1000LL * 1000LL)));
GNUNET_assert (ret > 0);
j = json_string (mystr);
GNUNET_free (mystr);
return j;
}
/**
* Convert RSA public key to JSON.
*
* @param pk public key to convert
* @return corresponding JSON encoding
*/
json_t *
TALER_json_from_rsa_public_key (struct GNUNET_CRYPTO_rsa_PublicKey *pk)
{
char *buf;
size_t buf_len;
json_t *ret;
buf_len = GNUNET_CRYPTO_rsa_public_key_encode (pk,
&buf);
ret = TALER_json_from_data (buf,
buf_len);
GNUNET_free (buf);
return ret;
}
/**
* Convert JSON to RSA public key.
*
* @param json JSON encoding to convert
* @return corresponding public key
*/
struct GNUNET_CRYPTO_rsa_PublicKey *
TALER_json_to_rsa_public_key (json_t *json)
{
const char *enc;
char *buf;
size_t len;
size_t buf_len;
struct GNUNET_CRYPTO_rsa_PublicKey *pk;
buf = NULL;
EXITIF (NULL == (enc = json_string_value (json)));
len = strlen (enc);
buf_len = (len * 5) / 8;
buf = GNUNET_malloc (buf_len);
EXITIF (GNUNET_OK !=
GNUNET_STRINGS_string_to_data (enc,
len,
buf,
buf_len));
EXITIF (NULL == (pk = GNUNET_CRYPTO_rsa_public_key_decode (buf,
buf_len)));
GNUNET_free (buf);
return pk;
EXITIF_exit:
GNUNET_free_non_null (buf);
return NULL;
}
/**
* Convert JSON to RSA signature.
*
* @param json JSON encoding to convert
* @return corresponding signature
*/
struct GNUNET_CRYPTO_rsa_Signature *
TALER_json_to_rsa_signature (json_t *json)
{
const char *enc;
char *buf;
size_t len;
size_t buf_len;
struct GNUNET_CRYPTO_rsa_Signature *sig;
buf = NULL;
EXITIF (NULL == (enc = json_string_value (json)));
len = strlen (enc);
buf_len = (len * 5) / 8;
buf = GNUNET_malloc (buf_len);
EXITIF (GNUNET_OK !=
GNUNET_STRINGS_string_to_data (enc,
len,
buf,
buf_len));
EXITIF (NULL == (sig = GNUNET_CRYPTO_rsa_signature_decode (buf,
buf_len)));
GNUNET_free (buf);
return sig;
EXITIF_exit:
GNUNET_free_non_null (buf);
return NULL;
}
/**
* Convert RSA signature to JSON.
*
* @param sig signature to convert
* @return corresponding JSON encoding
*/
json_t *
TALER_json_from_rsa_signature (struct GNUNET_CRYPTO_rsa_Signature *sig)
{
char *buf;
size_t buf_len;
json_t *ret;
buf_len = GNUNET_CRYPTO_rsa_signature_encode (sig,
&buf);
ret = TALER_json_from_data (buf,
buf_len);
GNUNET_free (buf);
return ret;
}
/**
* Convert binary data to a JSON string
* with the base32crockford encoding.
*
* @param data binary data
* @param size size of @a data in bytes
* @return json string that encodes @a data
*/
json_t *
TALER_json_from_data (const void *data,
size_t size)
{
char *buf;
json_t *json;
buf = GNUNET_STRINGS_data_to_string_alloc (data, size);
json = json_string (buf);
GNUNET_free (buf);
return json;
}
/**
* Parse given JSON object to Amount
*
* @param json the json object representing Amount
* @param[out] r_amount where the amount has to be written
* @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
*/
int
TALER_json_to_amount (json_t *json,
struct TALER_Amount *r_amount)
{
json_int_t value;
json_int_t fraction;
const char *currency;
memset (r_amount,
0,
sizeof (struct TALER_Amount));
if (0 != json_unpack (json,
"{s:I, s:I, s:s}",
"value", &value,
"fraction", &fraction,
"currency", &currency))
{
char *json_enc;
if (NULL == (json_enc = json_dumps (json,
JSON_COMPACT | JSON_ENCODE_ANY)))
{
GNUNET_break (0);
return GNUNET_SYSERR;
}
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Malformed JSON amount: %s\n",
json_enc);
free (json_enc);
return GNUNET_SYSERR;
}
if ( (value < 0) ||
(fraction < 0) ||
(value > UINT64_MAX) ||
(fraction > UINT32_MAX) )
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
if (strlen (currency) >= TALER_CURRENCY_LEN)
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
r_amount->value = (uint64_t) value;
r_amount->fraction = (uint32_t) fraction;
strcpy (r_amount->currency, currency);
(void) TALER_amount_normalize (r_amount);
return GNUNET_OK;
}
/**
* Parse given JSON object to absolute time.
*
* @param json the json object representing Amount
* @param[out] abs where the amount has to be written
* @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
*/
int
TALER_json_to_abs (json_t *json,
struct GNUNET_TIME_Absolute *abs)
{
const char *val;
unsigned long long int tval;
val = json_string_value (json);
if (NULL == val)
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
if ( (0 == strcasecmp (val,
"/forever/")) ||
(0 == strcasecmp (val,
"/never/")) )
{
*abs = GNUNET_TIME_UNIT_FOREVER_ABS;
return GNUNET_OK;
}
if (1 != sscanf (val,
"/Date(%llu)/",
&tval))
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
/* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Absolute */
abs->abs_value_us = tval * 1000LL * 1000LL;
if ( (abs->abs_value_us) / 1000LL / 1000LL != tval)
{
/* Integer overflow */
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
return GNUNET_OK;
}
/**
* Parse given JSON object to data
*
* @param json the json object representing data
* @param out the pointer to hold the parsed data.
* @param out_size the size of @a out
* @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
*/
int
TALER_json_to_data (json_t *json,
void *out,
size_t out_size)
{
const char *enc;
unsigned int len;
EXITIF (NULL == (enc = json_string_value (json)));
len = strlen (enc);
EXITIF (((len * 5) / 8) != out_size);
EXITIF (GNUNET_OK != GNUNET_STRINGS_string_to_data (enc, len, out, out_size));
return GNUNET_OK;
EXITIF_exit:
return GNUNET_SYSERR;
}
/**
* Hash a JSON for binary signing.
*
* @param[in] json some JSON value
* @param[out] hc resulting hash code
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
*/
int
TALER_hash_json (json_t *json,
struct GNUNET_HashCode *hc)
{
char *wire_enc;
size_t len;
if (NULL == (wire_enc = json_dumps (json,
JSON_COMPACT | JSON_SORT_KEYS)))
return GNUNET_SYSERR;
len = strlen (wire_enc) + 1;
GNUNET_CRYPTO_hash (wire_enc,
len,
hc);
free (wire_enc);
return GNUNET_OK;
}
/* End of util/json.c */

View File

@ -1,182 +0,0 @@
/*
This file is part of TALER
(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 util/test_json.c
* @brief Tests for Taler-specific crypto logic
* @author Christian Grothoff <christian@grothoff.org>
*/
#include "platform.h"
#include "taler_util.h"
#include "taler_json_lib.h"
/**
* Test amount conversion from/to JSON.
*
* @return 0 on success
*/
static int
test_amount ()
{
json_t *j;
struct TALER_Amount a1;
struct TALER_Amount a2;
GNUNET_assert (GNUNET_OK ==
TALER_string_to_amount ("EUR:4.3",
&a1));
j = TALER_json_from_amount (&a1);
GNUNET_assert (NULL != j);
GNUNET_assert (GNUNET_OK ==
TALER_json_to_amount (j,
&a2));
GNUNET_assert (0 ==
TALER_amount_cmp (&a1,
&a2));
json_decref (j);
return 0;
}
/**
* Test time conversion from/to JSON.
*
* @return 0 on success
*/
static int
test_time ()
{
json_t *j;
struct GNUNET_TIME_Absolute a1;
struct GNUNET_TIME_Absolute a2;
a1 = GNUNET_TIME_absolute_get ();
TALER_round_abs_time (&a1);
j = TALER_json_from_abs (a1);
GNUNET_assert (NULL != j);
GNUNET_assert (GNUNET_OK ==
TALER_json_to_abs (j,
&a2));
GNUNET_assert (a1.abs_value_us ==
a2.abs_value_us);
json_decref (j);
a1 = GNUNET_TIME_UNIT_FOREVER_ABS;
j = TALER_json_from_abs (a1);
GNUNET_assert (NULL != j);
GNUNET_assert (GNUNET_OK ==
TALER_json_to_abs (j,
&a2));
GNUNET_assert (a1.abs_value_us ==
a2.abs_value_us);
json_decref (j);
return 0;
}
/**
* Test raw (binary) conversion from/to JSON.
*
* @return 0 on success
*/
static int
test_raw ()
{
char blob[256];
char blob2[256];
unsigned int i;
json_t *j;
for (i=0;i<=256;i++)
{
memset (blob, i, i);
j = TALER_json_from_data (blob, i);
GNUNET_assert (NULL != j);
GNUNET_assert (GNUNET_OK ==
TALER_json_to_data (j,
blob2,
i));
GNUNET_assert (0 ==
memcmp (blob,
blob2,
i));
}
return 0;
}
/**
* Test rsa conversions from/to JSON.
*
* @return 0 on success
*/
static int
test_rsa ()
{
struct GNUNET_CRYPTO_rsa_PublicKey *pub;
struct GNUNET_CRYPTO_rsa_PublicKey *pub2;
struct GNUNET_CRYPTO_rsa_Signature *sig;
struct GNUNET_CRYPTO_rsa_Signature *sig2;
struct GNUNET_CRYPTO_rsa_PrivateKey *priv;
char msg[] = "Hello";
json_t *jp;
json_t *js;
priv = GNUNET_CRYPTO_rsa_private_key_create (1024);
pub = GNUNET_CRYPTO_rsa_private_key_get_public (priv);
sig = GNUNET_CRYPTO_rsa_sign (priv,
msg,
sizeof (msg));
GNUNET_assert (NULL != (jp = TALER_json_from_rsa_public_key (pub)));
GNUNET_assert (NULL != (js = TALER_json_from_rsa_signature (sig)));
GNUNET_assert (NULL != (pub2 = TALER_json_to_rsa_public_key (jp)));
GNUNET_assert (NULL != (sig2 = TALER_json_to_rsa_signature (js)));
GNUNET_break (0 ==
GNUNET_CRYPTO_rsa_signature_cmp (sig,
sig2));
GNUNET_break (0 ==
GNUNET_CRYPTO_rsa_public_key_cmp (pub,
pub2));
GNUNET_CRYPTO_rsa_signature_free (sig);
GNUNET_CRYPTO_rsa_signature_free (sig2);
GNUNET_CRYPTO_rsa_private_key_free (priv);
GNUNET_CRYPTO_rsa_public_key_free (pub);
GNUNET_CRYPTO_rsa_public_key_free (pub2);
return 0;
}
int
main(int argc,
const char *const argv[])
{
GNUNET_log_setup ("test-json",
"WARNING",
NULL);
if (0 != test_amount ())
return 1;
if (0 != test_time ())
return 1;
if (0 != test_raw ())
return 1;
if (0 != test_rsa ())
return 1;
/* FIXME: test EdDSA signature conversion... */
return 0;
}
/* end of test_json.c */

View File

@ -89,46 +89,6 @@ TALER_config_get_denom (struct GNUNET_CONFIGURATION_Handle *cfg,
}
/**
* Round a time value so that it is suitable for transmission
* via JSON encodings.
*
* @param at time to round
* @return #GNUNET_OK if time was already rounded, #GNUNET_NO if
* it was just now rounded
*/
int
TALER_round_abs_time (struct GNUNET_TIME_Absolute *at)
{
if (at->abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us)
return GNUNET_OK;
if (0 == at->abs_value_us % 1000000)
return GNUNET_OK;
at->abs_value_us -= at->abs_value_us % 1000000;
return GNUNET_NO;
}
/**
* Round a time value so that it is suitable for transmission
* via JSON encodings.
*
* @param rt time to round
* @return #GNUNET_OK if time was already rounded, #GNUNET_NO if
* it was just now rounded
*/
int
TALER_round_rel_time (struct GNUNET_TIME_Relative *rt)
{
if (rt->rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
return GNUNET_OK;
if (0 == rt->rel_value_us % 1000000)
return GNUNET_OK;
rt->rel_value_us -= rt->rel_value_us % 1000000;
return GNUNET_NO;
}
/**
* Load configuration by parsing all configuration
* files in the given directory.

View File

@ -1,441 +0,0 @@
/*
This file is part of TALER
Copyright (C) 2014, 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 util/wireformats.c
* @brief helper functions for JSON processing using libjansson
* @author Sree Harsha Totakura <sreeharsha@totakura.in>
* @author Christian Grothoff
*/
#include "platform.h"
#include <gnunet/gnunet_util_lib.h>
#include "taler_util.h"
/**
* Shorthand for exit jumps.
*/
#define EXITIF(cond) \
do { \
if (cond) { GNUNET_break (0); goto EXITIF_exit; } \
} while (0)
/**
* Shorthand for JSON parsing related exit jumps.
*/
#define UNPACK_EXITIF(cond) \
do { \
if (cond) { TALER_json_warn (error); goto EXITIF_exit; } \
} while (0)
/* Taken from GNU gettext */
/**
* Entry in the country table.
*/
struct table_entry
{
/**
* 2-Character international country code.
*/
const char *code;
/**
* Long English name of the country.
*/
const char *english;
};
/* Keep the following table in sync with gettext.
WARNING: the entries should stay sorted according to the code */
/**
* List of country codes.
*/
static const struct table_entry country_table[] =
{
{ "AE", "U.A.E." },
{ "AF", "Afghanistan" },
{ "AL", "Albania" },
{ "AM", "Armenia" },
{ "AN", "Netherlands Antilles" },
{ "AR", "Argentina" },
{ "AT", "Austria" },
{ "AU", "Australia" },
{ "AZ", "Azerbaijan" },
{ "BA", "Bosnia and Herzegovina" },
{ "BD", "Bangladesh" },
{ "BE", "Belgium" },
{ "BG", "Bulgaria" },
{ "BH", "Bahrain" },
{ "BN", "Brunei Darussalam" },
{ "BO", "Bolivia" },
{ "BR", "Brazil" },
{ "BT", "Bhutan" },
{ "BY", "Belarus" },
{ "BZ", "Belize" },
{ "CA", "Canada" },
{ "CG", "Congo" },
{ "CH", "Switzerland" },
{ "CI", "Cote d'Ivoire" },
{ "CL", "Chile" },
{ "CM", "Cameroon" },
{ "CN", "People's Republic of China" },
{ "CO", "Colombia" },
{ "CR", "Costa Rica" },
{ "CS", "Serbia and Montenegro" },
{ "CZ", "Czech Republic" },
{ "DE", "Germany" },
{ "DK", "Denmark" },
{ "DO", "Dominican Republic" },
{ "DZ", "Algeria" },
{ "EC", "Ecuador" },
{ "EE", "Estonia" },
{ "EG", "Egypt" },
{ "ER", "Eritrea" },
{ "ES", "Spain" },
{ "ET", "Ethiopia" },
{ "FI", "Finland" },
{ "FO", "Faroe Islands" },
{ "FR", "France" },
{ "GB", "United Kingdom" },
{ "GD", "Caribbean" },
{ "GE", "Georgia" },
{ "GL", "Greenland" },
{ "GR", "Greece" },
{ "GT", "Guatemala" },
{ "HK", "Hong Kong" },
{ "HK", "Hong Kong S.A.R." },
{ "HN", "Honduras" },
{ "HR", "Croatia" },
{ "HT", "Haiti" },
{ "HU", "Hungary" },
{ "ID", "Indonesia" },
{ "IE", "Ireland" },
{ "IL", "Israel" },
{ "IN", "India" },
{ "IQ", "Iraq" },
{ "IR", "Iran" },
{ "IS", "Iceland" },
{ "IT", "Italy" },
{ "JM", "Jamaica" },
{ "JO", "Jordan" },
{ "JP", "Japan" },
{ "KE", "Kenya" },
{ "KG", "Kyrgyzstan" },
{ "KH", "Cambodia" },
{ "KR", "South Korea" },
{ "KW", "Kuwait" },
{ "KZ", "Kazakhstan" },
{ "LA", "Laos" },
{ "LB", "Lebanon" },
{ "LI", "Liechtenstein" },
{ "LK", "Sri Lanka" },
{ "LT", "Lithuania" },
{ "LU", "Luxembourg" },
{ "LV", "Latvia" },
{ "LY", "Libya" },
{ "MA", "Morocco" },
{ "MC", "Principality of Monaco" },
{ "MD", "Moldava" },
{ "MD", "Moldova" },
{ "ME", "Montenegro" },
{ "MK", "Former Yugoslav Republic of Macedonia" },
{ "ML", "Mali" },
{ "MM", "Myanmar" },
{ "MN", "Mongolia" },
{ "MO", "Macau S.A.R." },
{ "MT", "Malta" },
{ "MV", "Maldives" },
{ "MX", "Mexico" },
{ "MY", "Malaysia" },
{ "NG", "Nigeria" },
{ "NI", "Nicaragua" },
{ "NL", "Netherlands" },
{ "NO", "Norway" },
{ "NP", "Nepal" },
{ "NZ", "New Zealand" },
{ "OM", "Oman" },
{ "PA", "Panama" },
{ "PE", "Peru" },
{ "PH", "Philippines" },
{ "PK", "Islamic Republic of Pakistan" },
{ "PL", "Poland" },
{ "PR", "Puerto Rico" },
{ "PT", "Portugal" },
{ "PY", "Paraguay" },
{ "QA", "Qatar" },
{ "RE", "Reunion" },
{ "RO", "Romania" },
{ "RS", "Serbia" },
{ "RU", "Russia" },
{ "RW", "Rwanda" },
{ "SA", "Saudi Arabia" },
{ "SE", "Sweden" },
{ "SG", "Singapore" },
{ "SI", "Slovenia" },
{ "SK", "Slovak" },
{ "SN", "Senegal" },
{ "SO", "Somalia" },
{ "SR", "Suriname" },
{ "SV", "El Salvador" },
{ "SY", "Syria" },
{ "TH", "Thailand" },
{ "TJ", "Tajikistan" },
{ "TM", "Turkmenistan" },
{ "TN", "Tunisia" },
{ "TR", "Turkey" },
{ "TT", "Trinidad and Tobago" },
{ "TW", "Taiwan" },
{ "TZ", "Tanzania" },
{ "UA", "Ukraine" },
{ "US", "United States" },
{ "UY", "Uruguay" },
{ "VA", "Vatican" },
{ "VE", "Venezuela" },
{ "VN", "Viet Nam" },
{ "YE", "Yemen" },
{ "ZA", "South Africa" },
{ "ZW", "Zimbabwe" }
};
/**
* Country code comparator function, for binary search with bsearch().
*
* @param ptr1 pointer to a `struct table_entry`
* @param ptr2 pointer to a `struct table_entry`
* @return result of strncmp()'ing the 2-digit country codes of the entries
*/
static int
cmp_country_code (const void *ptr1,
const void *ptr2)
{
const struct table_entry *cc1 = ptr1;
const struct table_entry *cc2 = ptr2;
return strncmp (cc1->code, cc2->code, 2);
}
/**
* Validates given IBAN according to the European Banking Standards. See:
* http://www.europeanpaymentscouncil.eu/documents/ECBS%20IBAN%20standard%20EBS204_V3.2.pdf
*
* @param iban the IBAN number to validate
* @return #GNUNET_YES if correctly formatted; #GNUNET_NO if not
*/
static int
validate_iban (const char *iban)
{
char cc[2];
char ibancpy[35];
struct table_entry cc_entry;
unsigned int len;
char *nbuf;
unsigned int i;
unsigned int j;
unsigned long long dividend;
unsigned long long remainder;
int nread;
int ret;
len = strlen (iban);
if (len > 34)
return GNUNET_NO;
strncpy (cc, iban, 2);
strncpy (ibancpy, iban + 4, len - 4);
strncpy (ibancpy + len - 4, iban, 4);
ibancpy[len] = '\0';
cc_entry.code = cc;
cc_entry.english = NULL;
if (NULL ==
bsearch (&cc_entry,
country_table,
sizeof (country_table) / sizeof (struct table_entry),
sizeof (struct table_entry),
&cmp_country_code))
return GNUNET_NO;
nbuf = GNUNET_malloc ((len * 2) + 1);
for (i=0, j=0; i < len; i++)
{
if (isalpha ((int) ibancpy[i]))
{
EXITIF(2 != snprintf(&nbuf[j],
3,
"%2u",
(ibancpy[i] - 'A' + 10)));
j += 2;
continue;
}
nbuf[j] = ibancpy[i];
j++;
}
for (j=0;'\0' != nbuf[j];j++)
GNUNET_assert (isdigit(nbuf[j]));
GNUNET_assert (sizeof(dividend) >= 8);
remainder = 0;
for (i=0; i<j; i+=16)
{
EXITIF (1 !=
(ret = sscanf (&nbuf[i],
"%16llu %n",
&dividend,
&nread)));
if (0 != remainder)
dividend += remainder * (pow (10, nread));
remainder = dividend % 97;
}
if (1 == remainder)
{
GNUNET_free (nbuf);
return GNUNET_YES;
}
EXITIF_exit:
GNUNET_free (nbuf);
return GNUNET_NO;
}
/**
* Validate SEPA account details.
*
* @param wire JSON with the SEPA details
* @return #GNUNET_YES if correctly formatted; #GNUNET_NO if not
*/
static int
validate_sepa (const json_t *wire)
{
json_error_t error;
const char *type;
const char *iban;
const char *name;
const char *bic;
uint64_t r;
const char *address;
UNPACK_EXITIF (0 != json_unpack_ex
((json_t *) wire,
&error, JSON_STRICT,
"{"
"s:s," /* TYPE: sepa */
"s:s," /* IBAN: iban */
"s:s," /* name: beneficiary name */
"s:s," /* BIC: beneficiary bank's BIC */
"s:i," /* r: random 64-bit integer nounce */
"s:s" /* address: address of the beneficiary */
"}",
"type", &type,
"IBAN", &iban,
"name", &name,
"bic", &bic,
"r", &r,
"address", &address));
if (1 != validate_iban (iban))
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"IBAN `%s' invalid\n",
iban);
return GNUNET_NO;
}
return GNUNET_YES;
EXITIF_exit:
return GNUNET_NO;
}
/**
* Validate TEST account details. The "test" format is used
* for testing, so this validator does nothing.
*
* @param wire JSON with the TEST details
* @return #GNUNET_YES if correctly formatted; #GNUNET_NO if not
*/
static int
validate_test (const json_t *wire)
{
return GNUNET_YES;
}
/**
* Handler for a wire format.
*/
struct FormatHandler
{
/**
* Type handled by this format handler.
*/
const char *type;
/**
* Function to call to evaluate the format.
*
* @param wire the JSON to evaluate
* @return #GNUNET_YES if correctly formatted; #GNUNET_NO if not
*/
int (*handler)(const json_t *wire);
};
/**
* Check if the given wire format JSON object is correctly formatted
*
* @param allowed NULL-terminated array of allowed wire format types
* @param wire the JSON wire format object
* @return #GNUNET_YES if correctly formatted; #GNUNET_NO if not
*/
int
TALER_json_validate_wireformat (const char **allowed,
const json_t *wire)
{
static const struct FormatHandler format_handlers[] = {
{ "SEPA", &validate_sepa },
{ "TEST", &validate_test },
{ NULL, NULL}
};
unsigned int i;
const char *stype;
json_error_t error;
UNPACK_EXITIF (0 != json_unpack_ex
((json_t *) wire,
&error, 0,
"{s:s}",
"type", &stype));
for (i=0;NULL != allowed[i];i++)
if (0 == strcasecmp (allowed[i],
stype))
break;
if (NULL == allowed[i])
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Wireformat `%s' does not match exchange's allowed formats\n",
stype);
return GNUNET_NO;
}
for (i=0;NULL != format_handlers[i].type;i++)
if (0 == strcasecmp (format_handlers[i].type,
stype))
return format_handlers[i].handler (wire);
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Wireformat `%s' not supported\n",
stype);
return GNUNET_NO;
EXITIF_exit:
return GNUNET_NO;
}
/* end of wireformats.c */

View File

@ -36,7 +36,9 @@ libtaler_plugin_wire_sepa_la_LIBADD = \
$(LTLIBINTL)
libtaler_plugin_wire_sepa_la_LDFLAGS = \
$(TALER_PLUGIN_LDFLAGS) \
$(top_builddir)/src/json/libtalerjson.la \
$(top_builddir)/src/util/libtalerutil.la \
-lgnunetjson \
-lgnunetutil $(XLIB)
@ -75,4 +77,3 @@ test_sepa_wireformat_LDADD = \
-ljansson \
libtalerwire.la \
$(top_builddir)/src/util/libtalerutil.la

View File

@ -1,6 +1,6 @@
/*
This file is part of TALER
Copyright (C) 2016 GNUnet e.V.
Copyright (C) 2016 GNUnet e.V. & 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
@ -23,6 +23,8 @@
*/
#include "platform.h"
#include "taler_wire_plugin.h"
#include "taler_signatures.h"
#include <gnunet/gnunet_json_lib.h>
/**
@ -58,6 +60,8 @@ sepa_amount_round (void *cls,
struct SepaClosure *sc = cls;
uint32_t delta;
if (NULL == sc->currency)
return GNUNET_SYSERR;
if (0 != strcasecmp (amount->currency,
sc->currency))
{
@ -347,42 +351,116 @@ validate_iban (const char *iban)
}
/**
* Verify that the signature in the @a json for /wire/sepa is valid.
*
* @param json json reply with the signature
* @param master_pub public key of the exchange to verify against
* @return #GNUNET_SYSERR if @a json is invalid,
* #GNUNET_NO if the method is unknown,
* #GNUNET_OK if the json is valid
*/
static int
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;
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 ("iban", &iban),
GNUNET_JSON_spec_string ("bic", &bic),
GNUNET_JSON_spec_end()
};
if (NULL == master_pub)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Skipping signature check as master public key not given\n");
return GNUNET_OK;
}
if (GNUNET_OK !=
GNUNET_JSON_parse (json, spec,
NULL, NULL))
{
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);
if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_SEPA_DETAILS,
&mp.purpose,
&exchange_sig.eddsa_signature,
&master_pub->eddsa_pub))
{
GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec);
return GNUNET_SYSERR;
}
GNUNET_JSON_parse_free (spec);
return GNUNET_OK;
}
/**
* Check if the given wire format JSON object is correctly formatted
*
* @param cls the @e cls of this struct with the plugin-specific state
* @param wire the JSON wire format object
* @param master_pub public key of the exchange to verify against
* @return #GNUNET_YES if correctly formatted; #GNUNET_NO if not
*/
static int
sepa_wire_validate (const json_t *wire)
sepa_wire_validate (void *cls,
const json_t *wire,
const struct TALER_MasterPublicKeyP *master_pub)
{
json_error_t error;
const char *type;
const char *iban;
const char *name;
const char *bic;
uint64_t r;
const char *address;
if (0 != json_unpack_ex
((json_t *) wire,
&error, JSON_STRICT,
&error, 0,
"{"
"s:s," /* TYPE: sepa */
"s:s," /* IBAN: iban */
"s:s," /* name: beneficiary name */
"s:s," /* BIC: beneficiary bank's BIC */
"s:i," /* r: random 64-bit integer nounce */
"s:s" /* address: address of the beneficiary */
"s:s," /* type: sepa */
"s:s," /* iban: IBAN */
"s:s," /* receiver_name: beneficiary name */
"s:s" /* bic: beneficiary bank's BIC */
"}",
"type", &type,
"IBAN", &iban,
"name", &name,
"bic", &bic,
"r", &r,
"address", &address))
"iban", &iban,
"receiver_name", &name,
"bic", &bic))
{
TALER_json_warn (error);
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"JSON parsing failed at %s:%u: %s (%s)\n",
__FILE__, __LINE__,
error.text, error.source);
json_dumpf (wire, stderr, 0);
fprintf (stderr, "\n");
return GNUNET_SYSERR;
}
if (0 != strcasecmp (type,
@ -400,6 +478,15 @@ sepa_wire_validate (const json_t *wire)
iban);
return GNUNET_NO;
}
/* FIXME: don't parse again, integrate properly... */
if (GNUNET_OK !=
verify_wire_sepa_signature_ok (wire,
master_pub))
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Signature invalid\n");
return GNUNET_NO;
}
return GNUNET_YES;
}
@ -499,6 +586,8 @@ libtaler_plugin_wire_sepa_init (void *cls)
struct TALER_WIRE_Plugin *plugin;
sc = GNUNET_new (struct SepaClosure);
if (NULL != cfg)
{
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_string (cfg,
"exchange",
@ -511,7 +600,7 @@ libtaler_plugin_wire_sepa_init (void *cls)
GNUNET_free (sc);
return NULL;
}
}
plugin = GNUNET_new (struct TALER_WIRE_Plugin);
plugin->cls = sc;
plugin->amount_round = &sepa_amount_round;
@ -536,7 +625,7 @@ libtaler_plugin_wire_sepa_done (void *cls)
struct TALER_WIRE_Plugin *plugin = cls;
struct SepaClosure *sc = plugin->cls;
GNUNET_free (sc->currency);
GNUNET_free_non_null (sc->currency);
GNUNET_free (sc);
GNUNET_free (plugin);
return NULL;

View File

@ -76,11 +76,15 @@ template_amount_round (void *cls,
/**
* Check if the given wire format JSON object is correctly formatted
*
* @param cls the @e cls of this struct with the plugin-specific state
* @param wire the JSON wire format object
* @param master_pub public key of the exchange to verify against
* @return #GNUNET_YES if correctly formatted; #GNUNET_NO if not
*/
static int
template_wire_validate (const json_t *wire)
template_wire_validate (void *cls,
const json_t *wire,
const struct TALER_MasterPublicKeyP *master_pub)
{
GNUNET_break (0);
return GNUNET_SYSERR;

View File

@ -1,6 +1,6 @@
/*
This file is part of TALER
Copyright (C) 2016 GNUnet e.V.
Copyright (C) 2016 GNUnet e.V. & 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
@ -215,6 +215,8 @@ test_amount_round (void *cls,
struct TestClosure *tc = cls;
uint32_t delta;
if (NULL == tc->currency)
return GNUNET_SYSERR; /* not configured with currency */
if (0 != strcasecmp (amount->currency,
tc->currency))
{
@ -235,11 +237,15 @@ test_amount_round (void *cls,
* Right now, the only thing we require is a field
* "account_number" which must contain a positive 53-bit integer.
*
* @param cls the @e cls of this struct with the plugin-specific state
* @param wire the JSON wire format object
* @param master_pub public key of the exchange to verify against
* @return #GNUNET_YES if correctly formatted; #GNUNET_NO if not
*/
static int
test_wire_validate (const json_t *wire)
test_wire_validate (void *cls,
const json_t *wire,
const struct TALER_MasterPublicKeyP *master_pub)
{
json_error_t error;
json_int_t account_no;
@ -368,7 +374,9 @@ test_prepare_wire_transfer (void *cls,
struct TALER_WIRE_PrepareHandle *pth;
if (GNUNET_YES !=
test_wire_validate (wire))
test_wire_validate (cls,
wire,
NULL))
{
GNUNET_break (0);
return NULL;
@ -456,6 +464,8 @@ test_execute_wire_transfer (void *cls,
json_int_t account_no;
struct BufFormatP bf;
if (NULL == tc->bank)
return NULL; /* not initialized with configuration, cannot do transfers */
if ( (buf_size <= sizeof (struct BufFormatP)) ||
('\0' != buf[buf_size -1]) )
{
@ -476,7 +486,9 @@ test_execute_wire_transfer (void *cls,
return NULL;
}
GNUNET_assert (GNUNET_YES ==
test_wire_validate (wire));
test_wire_validate (NULL,
wire,
NULL));
if (0 !=
json_unpack_ex (wire,
&error,
@ -545,6 +557,9 @@ libtaler_plugin_wire_test_init (void *cls)
struct TALER_WIRE_Plugin *plugin;
char *uri;
tc = GNUNET_new (struct TestClosure);
if (NULL != cfg)
{
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_string (cfg,
"wire-test",
@ -554,9 +569,9 @@ libtaler_plugin_wire_test_init (void *cls)
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
"wire-test",
"BANK_URI");
GNUNET_free (tc);
return NULL;
}
tc = GNUNET_new (struct TestClosure);
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_number (cfg,
"wire-test",
@ -591,7 +606,7 @@ libtaler_plugin_wire_test_init (void *cls)
GNUNET_free (tc);
return NULL;
}
}
plugin = GNUNET_new (struct TALER_WIRE_Plugin);
plugin->cls = tc;
plugin->amount_round = &test_amount_round;
@ -621,8 +636,12 @@ libtaler_plugin_wire_test_done (void *cls)
GNUNET_SCHEDULER_cancel (tc->bt);
tc->bt = NULL;
}
if (NULL != tc->bank)
{
TALER_BANK_fini (tc->bank);
GNUNET_free (tc->currency);
tc->bank = NULL;
}
GNUNET_free_non_null (tc->currency);
GNUNET_free (tc);
GNUNET_free (plugin);
return NULL;

View File

@ -28,37 +28,37 @@
/* Valid SEPA data */
static const char * const valid_wire_str =
"{ \"type\":\"SEPA\", \
\"IBAN\":\"DE67830654080004822650\", \
\"name\":\"GNUnet e.V.\", \
\"iban\":\"DE67830654080004822650\", \
\"receiver_name\":\"GNUnet e.V.\", \
\"bic\":\"GENODEF1SLR\", \
\"r\":123456789, \
\"salt\":\"123456789\", \
\"address\": \"foobar\"}";
/* IBAN has wrong country code */
static const char * const invalid_wire_str =
"{ \"type\":\"SEPA\", \
\"IBAN\":\"XX67830654080004822650\", \
\"name\":\"GNUnet e.V.\", \
\"iban\":\"XX67830654080004822650\", \
\"receiver_name\":\"GNUnet e.V.\", \
\"bic\":\"GENODEF1SLR\", \
\"r\":123456789, \
\"salt\":\"123456789\", \
\"address\": \"foobar\"}";
/* IBAN has wrong checksum */
static const char * const invalid_wire_str2 =
"{ \"type\":\"SEPA\", \
\"IBAN\":\"DE67830654080004822651\", \
\"name\":\"GNUnet e.V.\", \
\"iban\":\"DE67830654080004822651\", \
\"receiver_name\":\"GNUnet e.V.\", \
\"bic\":\"GENODEF1SLR\", \
\"r\":123456789, \
\"salt\":\"123456789\", \
\"address\": \"foobar\"}";
/* Unsupported wireformat type */
static const char * const unsupported_wire_str =
"{ \"type\":\"unsupported\", \
\"IBAN\":\"DE67830654080004822650\", \
\"name\":\"GNUnet e.V.\", \
\"iban\":\"DE67830654080004822650\", \
\"receiver_name\":\"GNUnet e.V.\", \
\"bic\":\"GENODEF1SLR\", \
\"r\":123456789, \
\"salt\":\"123456789\", \
\"address\": \"foobar\"}";
@ -85,16 +85,24 @@ main(int argc,
GNUNET_assert (NULL != plugin);
(void) memset(&error, 0, sizeof(error));
GNUNET_assert (NULL != (wire = json_loads (unsupported_wire_str, 0, NULL)));
GNUNET_assert (GNUNET_YES != plugin->wire_validate (wire));
GNUNET_assert (GNUNET_YES != plugin->wire_validate (NULL,
wire,
NULL));
json_decref (wire);
GNUNET_assert (NULL != (wire = json_loads (invalid_wire_str, 0, NULL)));
GNUNET_assert (GNUNET_NO == plugin->wire_validate (wire));
GNUNET_assert (GNUNET_NO == plugin->wire_validate (NULL,
wire,
NULL));
json_decref (wire);
GNUNET_assert (NULL != (wire = json_loads (invalid_wire_str2, 0, NULL)));
GNUNET_assert (GNUNET_NO == plugin->wire_validate (wire));
GNUNET_assert (GNUNET_NO == plugin->wire_validate (NULL,
wire,
NULL));
json_decref (wire);
GNUNET_assert (NULL != (wire = json_loads (valid_wire_str, 0, &error)));
ret = plugin->wire_validate (wire);
ret = plugin->wire_validate (NULL,
wire,
NULL);
json_decref (wire);
TALER_WIRE_plugin_unload (plugin);
GNUNET_CONFIGURATION_destroy (cfg);