refactor to eliminate duplicated JSON parsing logic (#4150)

This commit is contained in:
Christian Grothoff 2016-03-19 19:16:35 +01:00
parent 3d5e096fa2
commit 737e3f4bf6
10 changed files with 345 additions and 1281 deletions

View File

@ -113,12 +113,12 @@ TMH_ADMIN_handler_admin_add_incoming (struct TMH_RequestHandler *rh,
struct GNUNET_TIME_Absolute at; struct GNUNET_TIME_Absolute at;
json_t *wire; json_t *wire;
json_t *root; json_t *root;
struct TMH_PARSE_FieldSpecification spec[] = { struct GNUNET_JSON_Specification spec[] = {
TMH_PARSE_member_fixed ("reserve_pub", &reserve_pub), GNUNET_JSON_spec_fixed_auto ("reserve_pub", &reserve_pub),
TMH_PARSE_member_amount ("amount", &amount), TALER_JSON_spec_amount ("amount", &amount),
TMH_PARSE_member_time_abs ("execution_date", &at), GNUNET_JSON_spec_absolute_time ("execution_date", &at),
TMH_PARSE_member_object ("wire", &wire), GNUNET_JSON_spec_json ("wire", &wire),
TMH_PARSE_MEMBER_END GNUNET_JSON_spec_end ()
}; };
int res; int res;
@ -148,7 +148,7 @@ TMH_ADMIN_handler_admin_add_incoming (struct TMH_RequestHandler *rh,
TMH_json_validate_wireformat (wire)) TMH_json_validate_wireformat (wire))
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
TMH_PARSE_release_data (spec); GNUNET_JSON_parse_free (spec);
return TMH_RESPONSE_reply_arg_unknown (connection, return TMH_RESPONSE_reply_arg_unknown (connection,
"wire"); "wire");
} }
@ -157,7 +157,7 @@ TMH_ADMIN_handler_admin_add_incoming (struct TMH_RequestHandler *rh,
&amount, &amount,
at, at,
wire); wire);
TMH_PARSE_release_data (spec); GNUNET_JSON_parse_free (spec);
return res; return res;
} }

View File

@ -140,19 +140,19 @@ parse_and_handle_deposit_request (struct MHD_Connection *connection,
struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki; struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
struct TMH_KS_StateHandle *ks; struct TMH_KS_StateHandle *ks;
struct GNUNET_HashCode my_h_wire; struct GNUNET_HashCode my_h_wire;
struct TMH_PARSE_FieldSpecification spec[] = { struct GNUNET_JSON_Specification spec[] = {
TMH_PARSE_member_denomination_public_key ("denom_pub", &deposit.coin.denom_pub), TALER_JSON_spec_denomination_public_key ("denom_pub", &deposit.coin.denom_pub),
TMH_PARSE_member_denomination_signature ("ub_sig", &deposit.coin.denom_sig), TALER_JSON_spec_denomination_signature ("ub_sig", &deposit.coin.denom_sig),
TMH_PARSE_member_fixed ("coin_pub", &deposit.coin.coin_pub), GNUNET_JSON_spec_fixed_auto ("coin_pub", &deposit.coin.coin_pub),
TMH_PARSE_member_fixed ("merchant_pub", &deposit.merchant_pub), GNUNET_JSON_spec_fixed_auto ("merchant_pub", &deposit.merchant_pub),
TMH_PARSE_member_fixed ("H_contract", &deposit.h_contract), GNUNET_JSON_spec_fixed_auto ("H_contract", &deposit.h_contract),
TMH_PARSE_member_fixed ("H_wire", &deposit.h_wire), GNUNET_JSON_spec_fixed_auto ("H_wire", &deposit.h_wire),
TMH_PARSE_member_fixed ("coin_sig", &deposit.csig), GNUNET_JSON_spec_fixed_auto ("coin_sig", &deposit.csig),
TMH_PARSE_member_uint64 ("transaction_id", &deposit.transaction_id), GNUNET_JSON_spec_uint64 ("transaction_id", &deposit.transaction_id),
TMH_PARSE_member_time_abs ("timestamp", &deposit.timestamp), GNUNET_JSON_spec_absolute_time ("timestamp", &deposit.timestamp),
TMH_PARSE_member_time_abs ("refund_deadline", &deposit.refund_deadline), GNUNET_JSON_spec_absolute_time ("refund_deadline", &deposit.refund_deadline),
TMH_PARSE_member_time_abs ("edate", &deposit.wire_deadline), GNUNET_JSON_spec_absolute_time ("edate", &deposit.wire_deadline),
TMH_PARSE_MEMBER_END GNUNET_JSON_spec_end ()
}; };
memset (&deposit, 0, sizeof (deposit)); memset (&deposit, 0, sizeof (deposit));
@ -167,7 +167,7 @@ parse_and_handle_deposit_request (struct MHD_Connection *connection,
if (GNUNET_YES != if (GNUNET_YES !=
TMH_json_validate_wireformat (wire)) TMH_json_validate_wireformat (wire))
{ {
TMH_PARSE_release_data (spec); GNUNET_JSON_parse_free (spec);
return TMH_RESPONSE_reply_arg_unknown (connection, return TMH_RESPONSE_reply_arg_unknown (connection,
"wire"); "wire");
} }
@ -176,7 +176,7 @@ parse_and_handle_deposit_request (struct MHD_Connection *connection,
&my_h_wire)) &my_h_wire))
{ {
TALER_LOG_WARNING ("Failed to parse JSON wire format specification for /deposit request\n"); TALER_LOG_WARNING ("Failed to parse JSON wire format specification for /deposit request\n");
TMH_PARSE_release_data (spec); GNUNET_JSON_parse_free (spec);
return TMH_RESPONSE_reply_arg_invalid (connection, return TMH_RESPONSE_reply_arg_invalid (connection,
"wire"); "wire");
} }
@ -185,7 +185,7 @@ parse_and_handle_deposit_request (struct MHD_Connection *connection,
sizeof (struct GNUNET_HashCode))) sizeof (struct GNUNET_HashCode)))
{ {
/* Client hashed contract differently than we did, reject */ /* Client hashed contract differently than we did, reject */
TMH_PARSE_release_data (spec); GNUNET_JSON_parse_free (spec);
return TMH_RESPONSE_reply_arg_invalid (connection, return TMH_RESPONSE_reply_arg_invalid (connection,
"H_wire"); "H_wire");
} }
@ -196,7 +196,7 @@ parse_and_handle_deposit_request (struct MHD_Connection *connection,
if (NULL == dki) if (NULL == dki)
{ {
TMH_KS_release (ks); TMH_KS_release (ks);
TMH_PARSE_release_data (spec); GNUNET_JSON_parse_free (spec);
return TMH_RESPONSE_reply_arg_unknown (connection, return TMH_RESPONSE_reply_arg_unknown (connection,
"denom_pub"); "denom_pub");
} }
@ -209,13 +209,13 @@ parse_and_handle_deposit_request (struct MHD_Connection *connection,
&deposit.deposit_fee)) &deposit.deposit_fee))
{ {
/* Total amount smaller than fee, invalid */ /* Total amount smaller than fee, invalid */
TMH_PARSE_release_data (spec); GNUNET_JSON_parse_free (spec);
return TMH_RESPONSE_reply_arg_invalid (connection, return TMH_RESPONSE_reply_arg_invalid (connection,
"f"); "f");
} }
res = verify_and_execute_deposit (connection, res = verify_and_execute_deposit (connection,
&deposit); &deposit);
TMH_PARSE_release_data (spec); GNUNET_JSON_parse_free (spec);
return res; return res;
} }
@ -247,10 +247,10 @@ TMH_DEPOSIT_handler_deposit (struct TMH_RequestHandler *rh,
json_t *wire; json_t *wire;
int res; int res;
struct TALER_Amount amount; struct TALER_Amount amount;
struct TMH_PARSE_FieldSpecification spec[] = { struct GNUNET_JSON_Specification spec[] = {
TMH_PARSE_member_object ("wire", &wire), GNUNET_JSON_spec_json ("wire", &wire),
TMH_PARSE_member_amount ("f", &amount), TALER_JSON_spec_amount ("f", &amount),
TMH_PARSE_MEMBER_END GNUNET_JSON_spec_end ()
}; };
res = TMH_PARSE_post_json (connection, res = TMH_PARSE_post_json (connection,
@ -274,7 +274,7 @@ TMH_DEPOSIT_handler_deposit (struct TMH_RequestHandler *rh,
json, json,
&amount, &amount,
wire); wire);
TMH_PARSE_release_data (spec); GNUNET_JSON_parse_free (spec);
json_decref (json); json_decref (json);
return res; return res;
} }

View File

@ -1,6 +1,6 @@
/* /*
This file is part of TALER 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 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 terms of the GNU Affero General Public License as published by the Free Software
@ -141,89 +141,6 @@ buffer_append (struct Buffer *buf,
} }
/**
* Release all memory allocated for the variable-size fields in
* the parser specification.
*
* @param spec specification to free
* @param spec_len number of items in @a spec to look at
*/
static void
release_data (struct TMH_PARSE_FieldSpecification *spec,
unsigned int spec_len)
{
unsigned int i;
for (i=0; i < spec_len; i++)
{
switch (spec[i].command)
{
case TMH_PARSE_JNC_FIELD:
GNUNET_break (0);
return;
case TMH_PARSE_JNC_INDEX:
GNUNET_break (0);
return;
case TMH_PARSE_JNC_RET_DATA:
break;
case TMH_PARSE_JNC_RET_DATA_VAR:
if (NULL != spec[i].destination)
{
GNUNET_free (* (void**) spec[i].destination);
*(void**) spec[i].destination = NULL;
*spec[i].destination_size_out = 0;
}
break;
case TMH_PARSE_JNC_RET_TYPED_JSON:
{
json_t *json;
json = *(json_t **) spec[i].destination;
if (NULL != json)
{
json_decref (json);
*(json_t**) spec[i].destination = NULL;
}
}
break;
case TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY:
{
struct TALER_DenominationPublicKey *pk;
pk = spec[i].destination;
if (NULL != pk->rsa_public_key)
{
GNUNET_CRYPTO_rsa_public_key_free (pk->rsa_public_key);
pk->rsa_public_key = NULL;
}
}
break;
case TMH_PARSE_JNC_RET_RSA_SIGNATURE:
{
struct TALER_DenominationSignature *sig;
sig = spec[i].destination;
if (NULL != sig->rsa_signature)
{
GNUNET_CRYPTO_rsa_signature_free (sig->rsa_signature);
sig->rsa_signature = NULL;
}
}
break;
case TMH_PARSE_JNC_RET_AMOUNT:
memset (spec[i].destination,
0,
sizeof (struct TALER_Amount));
break;
case TMH_PARSE_JNC_RET_TIME_ABSOLUTE:
break;
case TMH_PARSE_JNC_RET_UINT64:
break;
}
}
}
/** /**
* Process a POST request containing a JSON object. This function * Process a POST request containing a JSON object. This function
* realizes an MHD POST processor that will (incrementally) process * realizes an MHD POST processor that will (incrementally) process
@ -349,8 +266,8 @@ TMH_PARSE_post_cleanup_callback (void *con_cls)
/** /**
* Extract base32crockford encoded data from request. * Extract base32crockford encoded data from request.
* *
* Queues an error response to the connection if the parameter is missing or * Queues an error response to the connection if the parameter is
* invalid. * missing or invalid.
* *
* @param connection the MHD connection * @param connection the MHD connection
* @param param_name the name of the parameter with the key * @param param_name the name of the parameter with the key
@ -390,759 +307,117 @@ TMH_PARSE_mhd_request_arg_data (struct MHD_Connection *connection,
} }
/**
* Extraxt variable-size base32crockford encoded data from request.
*
* Queues an error response to the connection if the parameter is missing
* or the encoding is invalid.
*
* @param connection the MHD connection
* @param param_name the name of the parameter with the key
* @param[out] out_data pointer to allocate buffer and store the result
* @param[out] out_size set to the size of the buffer allocated in @a out_data
* @return
* #GNUNET_YES if the the argument is present
* #GNUNET_NO if the argument is absent or malformed
* #GNUNET_SYSERR on internal error (error response could not be sent)
*/
int
TMH_PARSE_mhd_request_var_arg_data (struct MHD_Connection *connection,
const char *param_name,
void **out_data,
size_t *out_size)
{
const char *str;
size_t slen;
size_t olen;
void *out;
str = MHD_lookup_connection_value (connection,
MHD_GET_ARGUMENT_KIND,
param_name);
if (NULL == str)
{
return (MHD_NO ==
TMH_RESPONSE_reply_arg_missing (connection, param_name))
? GNUNET_SYSERR : GNUNET_NO;
}
slen = strlen (str);
olen = (slen * 5) / 8;
out = GNUNET_malloc (olen);
if (GNUNET_OK !=
GNUNET_STRINGS_string_to_data (str,
strlen (str),
out,
olen))
{
GNUNET_free (out);
*out_size = 0;
return (MHD_NO ==
TMH_RESPONSE_reply_arg_invalid (connection, param_name))
? GNUNET_SYSERR : GNUNET_NO;
}
*out_data = out;
*out_size = olen;
return GNUNET_OK;
}
/**
* Navigate through a JSON tree.
*
* Sends an error response if navigation is impossible (i.e.
* the JSON object is invalid)
*
* @param connection the connection to send an error response to
* @param root the JSON node to start the navigation at.
* @param ... navigation specification (see `enum TMH_PARSE_JsonNavigationCommand`)
* @return
* #GNUNET_YES if navigation was successful
* #GNUNET_NO if json is malformed, error response was generated
* #GNUNET_SYSERR on internal error (no response was generated,
* connection must be closed)
*/
int
TMH_PARSE_navigate_json (struct MHD_Connection *connection,
const json_t *root,
...)
{
va_list argp;
int ret;
json_t *path; /* what's our current path from 'root'? */
path = json_array ();
va_start (argp, root);
ret = 2; /* just not any of the valid return values */
while (2 == ret)
{
enum TMH_PARSE_JsonNavigationCommand command
= va_arg (argp,
enum TMH_PARSE_JsonNavigationCommand);
switch (command)
{
case TMH_PARSE_JNC_FIELD:
{
const char *fname = va_arg(argp, const char *);
json_array_append_new (path,
json_string (fname));
root = json_object_get (root,
fname);
if (NULL == root)
{
GNUNET_break_op (0);
ret = (MHD_YES ==
TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
"{s:s, s:s, s:O}",
"error", "missing field in JSON",
"field", fname,
"path", path))
? GNUNET_NO : GNUNET_SYSERR;
break;
}
}
break;
case TMH_PARSE_JNC_INDEX:
{
int fnum = va_arg(argp, int);
json_array_append_new (path,
json_integer (fnum));
root = json_array_get (root,
fnum);
if (NULL == root)
{
GNUNET_break_op (0);
ret = (MHD_YES ==
TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
"{s:s, s:O}",
"error", "missing index in JSON",
"path", path))
? GNUNET_NO : GNUNET_SYSERR;
break;
}
}
break;
case TMH_PARSE_JNC_RET_DATA:
{
void *where = va_arg (argp, void *);
size_t len = va_arg (argp, size_t);
const char *str;
int res;
str = json_string_value (root);
if (NULL == str)
{
GNUNET_break_op (0);
ret = (MHD_YES ==
TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
"{s:s, s:O}",
"error", "string expected",
"path", path))
? GNUNET_NO : GNUNET_SYSERR;
break;
}
res = GNUNET_STRINGS_string_to_data (str, strlen (str),
where, len);
if (GNUNET_OK != res)
{
GNUNET_break_op (0);
ret = (MHD_YES ==
TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
"{s:s, s:O}",
"error", "malformed binary data in JSON",
"path", path))
? GNUNET_NO : GNUNET_SYSERR;
break;
}
ret = GNUNET_OK;
}
break;
case TMH_PARSE_JNC_RET_DATA_VAR:
{
void **where = va_arg (argp, void **);
size_t *len = va_arg (argp, size_t *);
const char *str;
int res;
str = json_string_value (root);
if (NULL == str)
{
GNUNET_break_op (0);
ret = (MHD_YES ==
TMH_RESPONSE_reply_internal_error (connection,
"json_string_value() failed"))
? GNUNET_NO : GNUNET_SYSERR;
break;
}
*len = (strlen (str) * 5) / 8;
if (NULL != where)
{
*where = GNUNET_malloc (*len);
res = GNUNET_STRINGS_string_to_data (str,
strlen (str),
*where,
*len);
if (GNUNET_OK != res)
{
GNUNET_break_op (0);
GNUNET_free (*where);
*where = NULL;
*len = 0;
ret = (MHD_YES ==
TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
"{s:s, s:O}",
"error", "malformed binary data in JSON",
"path", path))
? GNUNET_NO : GNUNET_SYSERR;
break;
}
}
ret = GNUNET_OK;
}
break;
case TMH_PARSE_JNC_RET_TYPED_JSON:
{
int typ = va_arg (argp, int);
const json_t **r_json = va_arg (argp, const json_t **);
if ( (NULL == root) ||
( (-1 != typ) &&
(json_typeof (root) != typ)) )
{
GNUNET_break_op (0);
*r_json = NULL;
ret = (MHD_YES ==
TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
"{s:s, s:i, s:i, s:O}",
"error", "wrong JSON field type",
"type_expected", typ,
"type_actual", json_typeof (root),
"path", path))
? GNUNET_NO : GNUNET_SYSERR;
break;
}
*r_json = root;
json_incref ((json_t *) root);
ret = GNUNET_OK;
}
break;
case TMH_PARSE_JNC_RET_UINT64:
{
uint64_t *r_u64 = va_arg (argp, uint64_t *);
if (json_typeof (root) != JSON_INTEGER)
{
GNUNET_break_op (0);
ret = (MHD_YES ==
TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
"{s:s, s:s, s:i, s:O}",
"error", "wrong JSON field type",
"type_expected", "integer",
"type_actual", json_typeof (root),
"path", path))
? GNUNET_NO : GNUNET_SYSERR;
break;
}
*r_u64 = (uint64_t) json_integer_value (root);
ret = GNUNET_OK;
}
break;
case TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY:
{
struct TALER_DenominationPublicKey *where;
size_t len;
const char *str;
int res;
void *buf;
where = va_arg (argp,
struct TALER_DenominationPublicKey *);
str = json_string_value (root);
if (NULL == str)
{
GNUNET_break_op (0);
ret = (MHD_YES ==
TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
"{s:s, s:O}",
"error", "string expected",
"path", path))
? GNUNET_NO : GNUNET_SYSERR;
break;
}
len = (strlen (str) * 5) / 8;
buf = GNUNET_malloc (len);
res = GNUNET_STRINGS_string_to_data (str,
strlen (str),
buf,
len);
if (GNUNET_OK != res)
{
GNUNET_break_op (0);
GNUNET_free (buf);
ret = (MHD_YES ==
TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
"{s:s, s:O}",
"error", "malformed binary data in JSON",
"path", path))
? GNUNET_NO : GNUNET_SYSERR;
break;
}
where->rsa_public_key = GNUNET_CRYPTO_rsa_public_key_decode (buf,
len);
GNUNET_free (buf);
if (NULL == where->rsa_public_key)
{
GNUNET_break_op (0);
ret = (MHD_YES ==
TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
"{s:s, s:O}",
"error", "malformed RSA public key in JSON",
"path", path))
? GNUNET_NO : GNUNET_SYSERR;
break;
}
ret = GNUNET_OK;
break;
}
case TMH_PARSE_JNC_RET_RSA_SIGNATURE:
{
struct TALER_DenominationSignature *where;
size_t len;
const char *str;
int res;
void *buf;
where = va_arg (argp,
struct TALER_DenominationSignature *);
str = json_string_value (root);
if (NULL == str)
{
GNUNET_break_op (0);
ret = (MHD_YES ==
TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
"{s:s, s:O}",
"error", "string expected",
"path", path))
? GNUNET_NO : GNUNET_SYSERR;
break;
}
len = (strlen (str) * 5) / 8;
buf = GNUNET_malloc (len);
res = GNUNET_STRINGS_string_to_data (str,
strlen (str),
buf,
len);
if (GNUNET_OK != res)
{
GNUNET_break_op (0);
GNUNET_free (buf);
ret = (MHD_YES ==
TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
"{s:s, s:O}",
"error", "malformed binary data in JSON",
"path", path))
? GNUNET_NO : GNUNET_SYSERR;
break;
}
where->rsa_signature = GNUNET_CRYPTO_rsa_signature_decode (buf,
len);
GNUNET_free (buf);
if (NULL == where->rsa_signature)
{
GNUNET_break_op (0);
ret = (MHD_YES ==
TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
"{s:s, s:O}",
"error", "malformed RSA signature in JSON",
"path", path))
? GNUNET_NO : GNUNET_SYSERR;
break;
}
ret = GNUNET_OK;
break;
}
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 !=
GNUNET_JSON_parse ((json_t *) root,
spec,
NULL, NULL))
{
GNUNET_break_op (0);
ret = (MHD_YES !=
TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
"{s:s, s:O}",
"error", "Bad format",
"path", path))
? GNUNET_SYSERR : GNUNET_NO;
break;
}
if (0 != strcmp (where->currency,
TMH_exchange_currency_string))
{
GNUNET_break_op (0);
ret = (MHD_YES !=
TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
"{s:s, s:O, s:s}",
"error", "Currency not supported",
"path", path,
"currency", where->currency))
? GNUNET_SYSERR : GNUNET_NO;
memset (where, 0, sizeof (struct TALER_Amount));
break;
}
ret = GNUNET_OK;
break;
}
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 !=
GNUNET_JSON_parse ((json_t *) root,
spec,
NULL, NULL))
{
GNUNET_break_op (0);
ret = (MHD_YES !=
TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
"{s:s, s:s, s:O}",
"error", "Bad format",
"hint", "expected absolute time",
"path", path))
? GNUNET_SYSERR : GNUNET_NO;
break;
}
ret = GNUNET_OK;
break;
}
default:
GNUNET_break (0);
ret = (MHD_YES ==
TMH_RESPONSE_reply_internal_error (connection,
"unhandled value in switch"))
? GNUNET_NO : GNUNET_SYSERR;
break;
}
}
va_end (argp);
json_decref (path);
return ret;
}
/** /**
* Parse JSON object into components based on the given field * Parse JSON object into components based on the given field
* specification. * specification. Generates error response on parse errors.
* *
* @param connection the connection to send an error response to * @param connection the connection to send an error response to
* @param root the JSON node to start the navigation at. * @param root the JSON node to start the navigation at.
* @param spec field specification for the parser * @param[in,out] spec field specification for the parser
* @return * @return
* #GNUNET_YES if navigation was successful (caller is responsible * #GNUNET_YES if navigation was successful (caller is responsible
* for freeing allocated variable-size data using * for freeing allocated variable-size data using
* #TMH_PARSE_release_data() when done) * #GNUNET_JSON_parse_free() when done)
* #GNUNET_NO if json is malformed, error response was generated * #GNUNET_NO if json is malformed, error response was generated
* #GNUNET_SYSERR on internal error * #GNUNET_SYSERR on internal error
*/ */
int int
TMH_PARSE_json_data (struct MHD_Connection *connection, TMH_PARSE_json_data (struct MHD_Connection *connection,
const json_t *root, const json_t *root,
struct TMH_PARSE_FieldSpecification *spec) struct GNUNET_JSON_Specification *spec)
{ {
unsigned int i;
int ret; int ret;
const char *error_json_name;
unsigned int error_line;
ret = GNUNET_YES; ret = GNUNET_JSON_parse (root,
for (i=0; NULL != spec[i].field_name; i++) spec,
&error_json_name,
&error_line);
if (GNUNET_SYSERR == ret)
{ {
if (GNUNET_YES != ret) if (NULL == error_json_name)
break; error_json_name = "<no field>";
switch (spec[i].command) ret = (MHD_YES ==
{ TMH_RESPONSE_reply_json_pack (connection,
case TMH_PARSE_JNC_FIELD: MHD_HTTP_BAD_REQUEST,
GNUNET_break (0); "{s:s, s:s, s:I}",
return GNUNET_SYSERR; "error", "parse error",
case TMH_PARSE_JNC_INDEX: "field", error_json_name,
GNUNET_break (0); "line", (json_int_t) error_line))
return GNUNET_SYSERR; ? GNUNET_NO : GNUNET_SYSERR;
case TMH_PARSE_JNC_RET_DATA: return ret;
ret = TMH_PARSE_navigate_json (connection,
root,
TMH_PARSE_JNC_FIELD,
spec[i].field_name,
TMH_PARSE_JNC_RET_DATA,
spec[i].destination,
spec[i].destination_size_in);
break;
case TMH_PARSE_JNC_RET_DATA_VAR:
ret = TMH_PARSE_navigate_json (connection,
root,
TMH_PARSE_JNC_FIELD,
spec[i].field_name,
TMH_PARSE_JNC_RET_DATA_VAR,
(void **) spec[i].destination,
spec[i].destination_size_out);
break;
case TMH_PARSE_JNC_RET_TYPED_JSON:
ret = TMH_PARSE_navigate_json (connection,
root,
TMH_PARSE_JNC_FIELD,
spec[i].field_name,
TMH_PARSE_JNC_RET_TYPED_JSON,
spec[i].type,
spec[i].destination);
break;
case TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY:
ret = TMH_PARSE_navigate_json (connection,
root,
TMH_PARSE_JNC_FIELD,
spec[i].field_name,
TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY,
spec[i].destination);
break;
case TMH_PARSE_JNC_RET_RSA_SIGNATURE:
ret = TMH_PARSE_navigate_json (connection,
root,
TMH_PARSE_JNC_FIELD,
spec[i].field_name,
TMH_PARSE_JNC_RET_RSA_SIGNATURE,
spec[i].destination);
break;
case TMH_PARSE_JNC_RET_AMOUNT:
GNUNET_assert (sizeof (struct TALER_Amount) ==
spec[i].destination_size_in);
ret = TMH_PARSE_navigate_json (connection,
root,
TMH_PARSE_JNC_FIELD,
spec[i].field_name,
TMH_PARSE_JNC_RET_AMOUNT,
spec[i].destination);
break;
case TMH_PARSE_JNC_RET_TIME_ABSOLUTE:
GNUNET_assert (sizeof (struct GNUNET_TIME_Absolute) ==
spec[i].destination_size_in);
ret = TMH_PARSE_navigate_json (connection,
root,
TMH_PARSE_JNC_FIELD,
spec[i].field_name,
TMH_PARSE_JNC_RET_TIME_ABSOLUTE,
spec[i].destination);
break;
case TMH_PARSE_JNC_RET_UINT64:
GNUNET_assert (sizeof (uint64_t) ==
spec[i].destination_size_in);
ret = TMH_PARSE_navigate_json (connection,
root,
TMH_PARSE_JNC_FIELD,
spec[i].field_name,
TMH_PARSE_JNC_RET_UINT64,
spec[i].destination);
break;
}
} }
if (GNUNET_YES != ret) return GNUNET_YES;
release_data (spec,
i - 1);
return ret;
} }
/** /**
* Release all memory allocated for the variable-size fields in * Parse JSON array into components based on the given field
* the parser specification. * specification. Generates error response on parse errors.
* *
* @param spec specification to free * @param connection the connection to send an error response to
* @param root the JSON node to start the navigation at.
* @param[in,out] spec field specification for the parser
* @param ... -1-terminated list of array offsets of type 'int'
* @return
* #GNUNET_YES if navigation was successful (caller is responsible
* for freeing allocated variable-size data using
* #GNUNET_JSON_parse_free() when done)
* #GNUNET_NO if json is malformed, error response was generated
* #GNUNET_SYSERR on internal error
*/ */
void int
TMH_PARSE_release_data (struct TMH_PARSE_FieldSpecification *spec) TMH_PARSE_json_array (struct MHD_Connection *connection,
const json_t *root,
struct GNUNET_JSON_Specification *spec,
...)
{ {
unsigned int i; int ret;
const char *error_json_name;
unsigned int error_line;
va_list ap;
json_int_t dim;
for (i=0; NULL != spec[i].field_name; i++) ; va_start (ap, spec);
release_data (spec, i); dim = 0;
while ( (-1 != (ret = va_arg (ap, int))) &&
(NULL != root) )
{
dim++;
root = json_array_get (root, ret);
}
if (NULL == root)
{
ret = (MHD_YES ==
TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
"{s:s, s:I}",
"error", "parse error",
"dimension", dim))
? GNUNET_NO : GNUNET_SYSERR;
return ret;
}
ret = GNUNET_JSON_parse (root,
spec,
&error_json_name,
&error_line);
if (GNUNET_SYSERR == ret)
{
if (NULL == error_json_name)
error_json_name = "<no field>";
ret = (MHD_YES ==
TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
"{s:s, s:s, s:I}",
"error", "parse error",
"field", error_json_name,
"line", (json_int_t) error_line))
? GNUNET_NO : GNUNET_SYSERR;
return ret;
}
return GNUNET_YES;
} }
/**
* Generate line in parser specification for 64-bit integer
* given as an integer in JSON.
*
* @param field name of the field
* @param[out] u64 integer to initialize
* @return corresponding field spec
*/
struct TMH_PARSE_FieldSpecification
TMH_PARSE_member_uint64 (const char *field,
uint64_t *u64)
{
struct TMH_PARSE_FieldSpecification ret =
{ field, (void *) u64, sizeof (uint64_t), NULL, TMH_PARSE_JNC_RET_UINT64, 0 };
return ret;
}
/**
* Generate line in parser specification for JSON object value.
*
* @param field name of the field
* @param[out] jsonp address of pointer to JSON to initialize
* @return corresponding field spec
*/
struct TMH_PARSE_FieldSpecification
TMH_PARSE_member_object (const char *field,
json_t **jsonp)
{
struct TMH_PARSE_FieldSpecification ret =
{ field, jsonp, 0, NULL, TMH_PARSE_JNC_RET_TYPED_JSON, JSON_OBJECT };
*jsonp = NULL;
return ret;
}
/**
* Generate line in parser specification for JSON array value.
*
* @param field name of the field
* @param[out] jsonp address of JSON pointer to initialize
* @return corresponding field spec
*/
struct TMH_PARSE_FieldSpecification
TMH_PARSE_member_array (const char *field,
json_t **jsonp)
{
struct TMH_PARSE_FieldSpecification ret =
{ field, jsonp, 0, NULL, TMH_PARSE_JNC_RET_TYPED_JSON, JSON_ARRAY };
*jsonp = NULL;
return ret;
}
/**
* Generate line in parser specification for an absolute time.
*
* @param field name of the field
* @param[out] atime time to initialize
*/
struct TMH_PARSE_FieldSpecification
TMH_PARSE_member_time_abs (const char *field,
struct GNUNET_TIME_Absolute *atime)
{
struct TMH_PARSE_FieldSpecification ret =
{ field, atime, sizeof(struct GNUNET_TIME_Absolute), NULL, TMH_PARSE_JNC_RET_TIME_ABSOLUTE, 0 };
return ret;
}
/**
* Generate line in parser specification for RSA public key.
*
* @param field name of the field
* @param[out] pk key to initialize
* @return corresponding field spec
*/
struct TMH_PARSE_FieldSpecification
TMH_PARSE_member_denomination_public_key (const char *field,
struct TALER_DenominationPublicKey *pk)
{
struct TMH_PARSE_FieldSpecification ret =
{ field, pk, 0, NULL, TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY, 0 };
pk->rsa_public_key = NULL;
return ret;
}
/**
* Generate line in parser specification for RSA public key.
*
* @param field name of the field
* @param sig the signature to initialize
* @return corresponding field spec
*/
struct TMH_PARSE_FieldSpecification
TMH_PARSE_member_denomination_signature (const char *field,
struct TALER_DenominationSignature *sig)
{
struct TMH_PARSE_FieldSpecification ret =
{ field, sig, 0, NULL, TMH_PARSE_JNC_RET_RSA_SIGNATURE, 0 };
sig->rsa_signature = NULL;
return ret;
}
/**
* Generate line in parser specification for an amount.
*
* @param field name of the field
* @param amount a `struct TALER_Amount *` to initialize
* @return corresponding field spec
*/
struct TMH_PARSE_FieldSpecification
TMH_PARSE_member_amount (const char *field,
struct TALER_Amount *amount)
{
struct TMH_PARSE_FieldSpecification ret =
{ field, amount, sizeof(struct TALER_Amount), NULL, TMH_PARSE_JNC_RET_AMOUNT, 0 };
memset (amount, 0, sizeof (struct TALER_Amount));
return ret;
}
/**
* Generate line in parser specification for variable-size value.
*
* @param field name of the field
* @param[out] ptr pointer to initialize
* @param[out] ptr_size size to initialize
* @return corresponding field spec
*/
struct TMH_PARSE_FieldSpecification
TMH_PARSE_member_variable (const char *field,
void **ptr,
size_t *ptr_size)
{
struct TMH_PARSE_FieldSpecification ret =
{ field, ptr, 0, ptr_size, TMH_PARSE_JNC_RET_DATA_VAR, 0 };
*ptr = NULL;
return ret;
}
/* end of taler-exchange-httpd_parsing.c */ /* end of taler-exchange-httpd_parsing.c */

View File

@ -1,6 +1,6 @@
/* /*
This file is part of TALER 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 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 terms of the GNU Affero General Public License as published by the Free Software
@ -26,6 +26,7 @@
#include <microhttpd.h> #include <microhttpd.h>
#include <jansson.h> #include <jansson.h>
#include "taler_util.h" #include "taler_util.h"
#include "taler_json_lib.h"
/** /**
@ -71,149 +72,6 @@ void
TMH_PARSE_post_cleanup_callback (void *con_cls); TMH_PARSE_post_cleanup_callback (void *con_cls);
/**
* Constants for JSON navigation description.
*/
enum TMH_PARSE_JsonNavigationCommand
{
/**
* Access a field.
* Param: const char *
*/
TMH_PARSE_JNC_FIELD,
/**
* Access an array index.
* Param: int
*/
TMH_PARSE_JNC_INDEX,
/**
* Return base32crockford encoded data of
* constant size.
* Params: (void *, size_t)
*/
TMH_PARSE_JNC_RET_DATA,
/**
* Return base32crockford encoded data of
* variable size.
* Params: (void **, size_t *)
*/
TMH_PARSE_JNC_RET_DATA_VAR,
/**
* Return a json object, which must be
* of the given type (JSON_* type constants,
* or -1 for any type).
* Params: (int, json_t **)
*/
TMH_PARSE_JNC_RET_TYPED_JSON,
/**
* Return a `struct GNUNET_CRYPTO_rsa_PublicKey` which was
* encoded as variable-size base32crockford encoded data.
*/
TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY,
/**
* Return a `struct GNUNET_CRYPTO_rsa_Signature` which was
* encoded as variable-size base32crockford encoded data.
*/
TMH_PARSE_JNC_RET_RSA_SIGNATURE,
/**
* Return a `struct TALER_Amount` which was
* encoded within its own json object.
*/
TMH_PARSE_JNC_RET_AMOUNT,
/**
* Return a `struct GNUNET_TIME_Absolute` which was
* encoded within its own json object.
* Param: struct GNUNET_TIME_Absolute *
*/
TMH_PARSE_JNC_RET_TIME_ABSOLUTE,
/**
* Return a `uint64_t` which was
* encoded as a JSON integer.
* Param: uint64_t *
*/
TMH_PARSE_JNC_RET_UINT64
};
/**
* Navigate through a JSON tree.
*
* Sends an error response if navigation is impossible (i.e.
* the JSON object is invalid)
*
* @param connection the connection to send an error response to
* @param root the JSON node to start the navigation at.
* @param ... navigation specification (see `enum TMH_PARSE_JsonNavigationCommand`)
* @return
* #GNUNET_YES if navigation was successful
* #GNUNET_NO if json is malformed, error response was generated
* #GNUNET_SYSERR on internal error
*/
int
TMH_PARSE_navigate_json (struct MHD_Connection *connection,
const json_t *root,
...);
/**
* @brief Specification for how to parse a JSON field.
*/
struct TMH_PARSE_FieldSpecification
{
/**
* Name of the field. NULL only to terminate array.
*/
const char *field_name;
/**
* Where to store the result. Must have exactly
* @e destination_size bytes, except if @e destination_size is zero.
* NULL to skip assignment (but check presence of the value).
*/
void *destination;
/**
* How big should the result be, 0 for variable size. In
* this case, @e destination must be a "void **", pointing
* to a location that is currently NULL and is to be allocated.
*/
size_t destination_size_in;
/**
* @e destination_size_out will then be set to the size of the
* value that was stored in @e destination (useful for
* variable-size allocations).
*/
size_t *destination_size_out;
/**
* Navigation command to use to extract the value. Note that
* #TMH_PARSE_JNC_RET_DATA or #TMH_PARSE_JNC_RET_DATA_VAR must be used for @e
* destination_size_in and @e destination_size_out to have a
* meaning. #TMH_PARSE_JNC_FIELD and #TMH_PARSE_JNC_INDEX must not be used here!
*/
enum TMH_PARSE_JsonNavigationCommand command;
/**
* JSON type to use, only meaningful in connection with a @e command
* value of #TMH_PARSE_JNC_RET_TYPED_JSON. Typical values are
* #JSON_ARRAY and #JSON_OBJECT.
*/
int type;
};
/** /**
* Parse JSON object into components based on the given field * Parse JSON object into components based on the given field
* specification. * specification.
@ -224,139 +82,36 @@ struct TMH_PARSE_FieldSpecification
* @return * @return
* #GNUNET_YES if navigation was successful (caller is responsible * #GNUNET_YES if navigation was successful (caller is responsible
* for freeing allocated variable-size data using * for freeing allocated variable-size data using
* #TMH_PARSE_release_data() when done) * #GNUNET_JSON_parse_free() when done)
* #GNUNET_NO if json is malformed, error response was generated * #GNUNET_NO if json is malformed, error response was generated
* #GNUNET_SYSERR on internal error * #GNUNET_SYSERR on internal error
*/ */
int int
TMH_PARSE_json_data (struct MHD_Connection *connection, TMH_PARSE_json_data (struct MHD_Connection *connection,
const json_t *root, const json_t *root,
struct TMH_PARSE_FieldSpecification *spec); struct GNUNET_JSON_Specification *spec);
/** /**
* Release all memory allocated for the variable-size fields in * Parse JSON array into components based on the given field
* the parser specification. * specification. Generates error response on parse errors.
* *
* @param spec specification to free * @param connection the connection to send an error response to
* @param root the JSON node to start the navigation at.
* @param[in,out] spec field specification for the parser
* @param ... -1-terminated list of array offsets of type 'int'
* @return
* #GNUNET_YES if navigation was successful (caller is responsible
* for freeing allocated variable-size data using
* #GNUNET_JSON_parse_free() when done)
* #GNUNET_NO if json is malformed, error response was generated
* #GNUNET_SYSERR on internal error
*/ */
void int
TMH_PARSE_release_data (struct TMH_PARSE_FieldSpecification *spec); TMH_PARSE_json_array (struct MHD_Connection *connection,
const json_t *root,
struct GNUNET_JSON_Specification *spec,
/** ...);
* Generate line in parser specification for fixed-size value.
*
* @param field name of the field
* @param value where to store the value
*/
#define TMH_PARSE_member_fixed(field,value) { field, value, sizeof (*value), NULL, TMH_PARSE_JNC_RET_DATA, 0 }
/**
* Generate line in parser specification for variable-size value.
*
* @param field name of the field
* @param[out] ptr pointer to initialize
* @param[out] ptr_size size to initialize
* @return corresponding field spec
*/
struct TMH_PARSE_FieldSpecification
TMH_PARSE_member_variable (const char *field,
void **ptr,
size_t *ptr_size);
/**
* Generate line in parser specification for 64-bit integer
* given as an integer in JSON.
*
* @param field name of the field
* @param[out] u64 integer to initialize
* @return corresponding field spec
*/
struct TMH_PARSE_FieldSpecification
TMH_PARSE_member_uint64 (const char *field,
uint64_t *u64);
/**
* Generate line in parser specification for JSON array value.
*
* @param field name of the field
* @param[out] jsonp address of JSON pointer to initialize
* @return corresponding field spec
*/
struct TMH_PARSE_FieldSpecification
TMH_PARSE_member_array (const char *field,
json_t **jsonp);
/**
* Generate line in parser specification for JSON object value.
*
* @param field name of the field
* @param[out] jsonp address of pointer to JSON to initialize
* @return corresponding field spec
*/
struct TMH_PARSE_FieldSpecification
TMH_PARSE_member_object (const char *field,
json_t **jsonp);
/**
* Generate line in parser specification for RSA public key.
*
* @param field name of the field
* @param[out] pk key to initialize
* @return corresponding field spec
*/
struct TMH_PARSE_FieldSpecification
TMH_PARSE_member_denomination_public_key (const char *field,
struct TALER_DenominationPublicKey *pk);
/**
* Generate line in parser specification for RSA public key.
*
* @param field name of the field
* @param sig the signature to initialize
* @return corresponding field spec
*/
struct TMH_PARSE_FieldSpecification
TMH_PARSE_member_denomination_signature (const char *field,
struct TALER_DenominationSignature *sig);
/**
* Generate line in parser specification for an amount.
*
* @param field name of the field
* @param[out] amount a `struct TALER_Amount *` to initialize
* @return corresponding field spec
*/
struct TMH_PARSE_FieldSpecification
TMH_PARSE_member_amount (const char *field,
struct TALER_Amount *amount);
/**
* Generate line in parser specification for an absolute time.
*
* @param field name of the field
* @param[out] atime time to initialize
* @return corresponding field spec
*/
struct TMH_PARSE_FieldSpecification
TMH_PARSE_member_time_abs (const char *field,
struct GNUNET_TIME_Absolute *atime);
/**
* Generate line in parser specification indicating the end of the spec.
*/
#define TMH_PARSE_MEMBER_END { NULL, NULL, 0, NULL, TMH_PARSE_JNC_FIELD, 0 }
/** /**
@ -381,28 +136,4 @@ TMH_PARSE_mhd_request_arg_data (struct MHD_Connection *connection,
size_t out_size); size_t out_size);
/**
* Extraxt variable-size base32crockford encoded data from request.
*
* Queues an error response to the connection if the parameter is missing
* or the encoding is invalid.
*
* @param connection the MHD connection
* @param param_name the name of the parameter with the key
* @param[out] out_data pointer to allocate buffer and store the result
* @param[out] out_size set to the size of the buffer allocated in @a out_data
* @return
* #GNUNET_YES if the the argument is present
* #GNUNET_NO if the argument is absent or malformed
* #GNUNET_SYSERR on internal error (error response could not be sent)
*/
int
TMH_PARSE_mhd_request_var_arg_data (struct MHD_Connection *connection,
const char *param_name,
void **out_data,
size_t *out_size);
#endif /* TALER_EXCHANGE_HTTPD_PARSING_H */ #endif /* TALER_EXCHANGE_HTTPD_PARSING_H */

View File

@ -192,13 +192,13 @@ get_coin_public_info (struct MHD_Connection *connection,
struct TALER_DenominationSignature sig; struct TALER_DenominationSignature sig;
struct TALER_DenominationPublicKey pk; struct TALER_DenominationPublicKey pk;
struct TALER_Amount amount; struct TALER_Amount amount;
struct TMH_PARSE_FieldSpecification spec[] = { struct GNUNET_JSON_Specification spec[] = {
TMH_PARSE_member_fixed ("coin_pub", &r_melt_detail->coin_info.coin_pub), GNUNET_JSON_spec_fixed_auto ("coin_pub", &r_melt_detail->coin_info.coin_pub),
TMH_PARSE_member_denomination_signature ("denom_sig", &sig), TALER_JSON_spec_denomination_signature ("denom_sig", &sig),
TMH_PARSE_member_denomination_public_key ("denom_pub", &pk), TALER_JSON_spec_denomination_public_key ("denom_pub", &pk),
TMH_PARSE_member_fixed ("confirm_sig", &melt_sig), GNUNET_JSON_spec_fixed_auto ("confirm_sig", &melt_sig),
TMH_PARSE_member_amount ("value_with_fee", &amount), TALER_JSON_spec_amount ("value_with_fee", &amount),
TMH_PARSE_MEMBER_END GNUNET_JSON_spec_end ()
}; };
ret = TMH_PARSE_json_data (connection, ret = TMH_PARSE_json_data (connection,
@ -216,7 +216,7 @@ get_coin_public_info (struct MHD_Connection *connection,
TALER_test_coin_valid (&r_melt_detail->coin_info)) TALER_test_coin_valid (&r_melt_detail->coin_info))
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
TMH_PARSE_release_data (spec); GNUNET_JSON_parse_free (spec);
r_melt_detail->coin_info.denom_sig.rsa_signature = NULL; r_melt_detail->coin_info.denom_sig.rsa_signature = NULL;
r_melt_detail->coin_info.denom_pub.rsa_public_key = NULL; r_melt_detail->coin_info.denom_pub.rsa_public_key = NULL;
return (MHD_YES == return (MHD_YES ==
@ -409,12 +409,16 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
{ {
char *buf; char *buf;
size_t buf_size; size_t buf_size;
struct GNUNET_JSON_Specification spec[] = {
TALER_JSON_spec_denomination_public_key (NULL,
&denom_pubs[i]),
GNUNET_JSON_spec_end ()
};
res = TMH_PARSE_navigate_json (connection, res = TMH_PARSE_json_array (connection,
new_denoms, new_denoms,
TMH_PARSE_JNC_INDEX, (int) i, spec,
TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY, i, -1);
&denom_pubs[i].rsa_public_key);
if (GNUNET_OK != res) if (GNUNET_OK != res)
{ {
res = (GNUNET_NO == res) ? MHD_YES : MHD_NO; res = (GNUNET_NO == res) ? MHD_YES : MHD_NO;
@ -436,6 +440,7 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
/* decode JSON data on coin to melt */ /* decode JSON data on coin to melt */
struct TALER_AmountNBO melt_amount; struct TALER_AmountNBO melt_amount;
// FIXME: check json_array_get() return value for NULL!
res = get_coin_public_info (connection, res = get_coin_public_info (connection,
json_array_get (melt_coins, i), json_array_get (melt_coins, i),
&coin_melt_details[i]); &coin_melt_details[i]);
@ -482,15 +487,23 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
char *link_enc; char *link_enc;
size_t link_enc_size; size_t link_enc_size;
struct TALER_EXCHANGEDB_RefreshCommitCoin *rcc = &commit_coin[i][j]; struct TALER_EXCHANGEDB_RefreshCommitCoin *rcc = &commit_coin[i][j];
struct GNUNET_JSON_Specification coin_spec[] = {
GNUNET_JSON_spec_varsize (NULL,
(void **) &rcc->coin_ev,
&rcc->coin_ev_size),
GNUNET_JSON_spec_end ()
};
struct GNUNET_JSON_Specification link_spec[] = {
GNUNET_JSON_spec_varsize (NULL,
(void **) &link_enc,
&link_enc_size),
GNUNET_JSON_spec_end ()
};
res = TMH_PARSE_navigate_json (connection, res = TMH_PARSE_json_array (connection,
coin_evs, coin_evs,
TMH_PARSE_JNC_INDEX, (int) i, coin_spec,
TMH_PARSE_JNC_INDEX, (int) j, i, j, -1);
TMH_PARSE_JNC_RET_DATA_VAR,
&rcc->coin_ev,
&rcc->coin_ev_size);
if (GNUNET_OK != res) if (GNUNET_OK != res)
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
@ -501,13 +514,10 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
GNUNET_CRYPTO_hash_context_read (hash_context, GNUNET_CRYPTO_hash_context_read (hash_context,
rcc->coin_ev, rcc->coin_ev,
rcc->coin_ev_size); rcc->coin_ev_size);
res = TMH_PARSE_navigate_json (connection, res = TMH_PARSE_json_array (connection,
link_encs, link_encs,
TMH_PARSE_JNC_INDEX, (int) i, link_spec,
TMH_PARSE_JNC_INDEX, (int) j, i, j, -1);
TMH_PARSE_JNC_RET_DATA_VAR,
&link_enc,
&link_enc_size);
if (GNUNET_OK != res) if (GNUNET_OK != res)
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
@ -520,7 +530,7 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
GNUNET_CRYPTO_hash_context_read (hash_context, GNUNET_CRYPTO_hash_context_read (hash_context,
link_enc, link_enc,
link_enc_size); link_enc_size);
GNUNET_free (link_enc); GNUNET_JSON_parse_free (link_spec);
} }
} }
@ -531,27 +541,29 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
for (j = 0; j < num_oldcoins; j++) for (j = 0; j < num_oldcoins; j++)
{ {
struct TALER_RefreshCommitLinkP *rcl = &commit_link[i][j]; struct TALER_RefreshCommitLinkP *rcl = &commit_link[i][j];
struct GNUNET_JSON_Specification trans_spec[] = {
GNUNET_JSON_spec_fixed_auto (NULL, &rcl->transfer_pub),
GNUNET_JSON_spec_end ()
};
struct GNUNET_JSON_Specification sec_spec[] = {
GNUNET_JSON_spec_fixed_auto (NULL, &rcl->shared_secret_enc),
GNUNET_JSON_spec_end ()
};
res = TMH_PARSE_navigate_json (connection, res = TMH_PARSE_json_array (connection,
transfer_pubs, transfer_pubs,
TMH_PARSE_JNC_INDEX, (int) i, trans_spec,
TMH_PARSE_JNC_INDEX, (int) j, i, j, -1);
TMH_PARSE_JNC_RET_DATA,
&rcl->transfer_pub,
sizeof (struct TALER_TransferPublicKeyP));
if (GNUNET_OK != res) if (GNUNET_OK != res)
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
res = (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; res = (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
goto cleanup; goto cleanup;
} }
res = TMH_PARSE_navigate_json (connection, res = TMH_PARSE_json_array (connection,
secret_encs, secret_encs,
TMH_PARSE_JNC_INDEX, (int) i, sec_spec,
TMH_PARSE_JNC_INDEX, (int) j, i, j, -1);
TMH_PARSE_JNC_RET_DATA,
&rcl->shared_secret_enc,
sizeof (struct TALER_EncryptedLinkSecretP));
if (GNUNET_OK != res) if (GNUNET_OK != res)
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
@ -646,15 +658,16 @@ TMH_REFRESH_handler_refresh_melt (struct TMH_RequestHandler *rh,
unsigned int num_oldcoins; unsigned int num_oldcoins;
unsigned int num_newcoins; unsigned int num_newcoins;
json_t *coin_detail; json_t *coin_detail;
json_t *trans_detail;
int res; int res;
struct TMH_PARSE_FieldSpecification spec[] = { struct GNUNET_JSON_Specification spec[] = {
TMH_PARSE_member_array ("new_denoms", &new_denoms), GNUNET_JSON_spec_json ("new_denoms", &new_denoms),
TMH_PARSE_member_array ("melt_coins", &melt_coins), GNUNET_JSON_spec_json ("melt_coins", &melt_coins),
TMH_PARSE_member_array ("coin_evs", &coin_evs), GNUNET_JSON_spec_json ("coin_evs", &coin_evs),
TMH_PARSE_member_array ("link_encs", &link_encs), GNUNET_JSON_spec_json ("link_encs", &link_encs),
TMH_PARSE_member_array ("transfer_pubs", &transfer_pubs), GNUNET_JSON_spec_json ("transfer_pubs", &transfer_pubs),
TMH_PARSE_member_array ("secret_encs", &secret_encs), GNUNET_JSON_spec_json ("secret_encs", &secret_encs),
TMH_PARSE_MEMBER_END GNUNET_JSON_spec_end ()
}; };
res = TMH_PARSE_post_json (connection, res = TMH_PARSE_post_json (connection,
@ -678,43 +691,36 @@ TMH_REFRESH_handler_refresh_melt (struct TMH_RequestHandler *rh,
if (TALER_CNC_KAPPA != json_array_size (coin_evs)) if (TALER_CNC_KAPPA != json_array_size (coin_evs))
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
TMH_PARSE_release_data (spec); GNUNET_JSON_parse_free (spec);
return TMH_RESPONSE_reply_arg_invalid (connection, return TMH_RESPONSE_reply_arg_invalid (connection,
"coin_evs"); "coin_evs");
} }
if (TALER_CNC_KAPPA != json_array_size (transfer_pubs)) if (TALER_CNC_KAPPA != json_array_size (transfer_pubs))
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
TMH_PARSE_release_data (spec); GNUNET_JSON_parse_free (spec);
return TMH_RESPONSE_reply_arg_invalid (connection, return TMH_RESPONSE_reply_arg_invalid (connection,
"transfer_pubs"); "transfer_pubs");
} }
res = TMH_PARSE_navigate_json (connection, coin_detail = json_array_get (coin_evs, 0);
coin_evs, if (NULL == coin_detail)
TMH_PARSE_JNC_INDEX, (int) 0,
TMH_PARSE_JNC_RET_TYPED_JSON,
JSON_ARRAY, &coin_detail);
if (GNUNET_OK != res)
{ {
// FIXME: generate proper HTTP response!
GNUNET_break_op (0); GNUNET_break_op (0);
TMH_PARSE_release_data (spec); GNUNET_JSON_parse_free (spec);
return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
} }
num_newcoins = json_array_size (coin_detail); num_newcoins = json_array_size (coin_detail);
json_decref (coin_detail);
res = TMH_PARSE_navigate_json (connection, trans_detail = json_array_get (transfer_pubs, 0);
transfer_pubs, if (NULL == trans_detail)
TMH_PARSE_JNC_INDEX, (int) 0,
TMH_PARSE_JNC_RET_TYPED_JSON,
JSON_ARRAY, &coin_detail);
if (GNUNET_OK != res)
{ {
// FIXME: generate proper HTTP response!
GNUNET_break_op (0); GNUNET_break_op (0);
TMH_PARSE_release_data (spec); GNUNET_JSON_parse_free (spec);
return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
} }
num_oldcoins = json_array_size (coin_detail); num_oldcoins = json_array_size (trans_detail);
json_decref (coin_detail);
res = handle_refresh_melt_json (connection, res = handle_refresh_melt_json (connection,
new_denoms, new_denoms,
melt_coins, melt_coins,
@ -724,7 +730,7 @@ TMH_REFRESH_handler_refresh_melt (struct TMH_RequestHandler *rh,
num_newcoins, num_newcoins,
coin_evs, coin_evs,
link_encs); link_encs);
TMH_PARSE_release_data (spec); GNUNET_JSON_parse_free (spec);
return res; return res;
} }
@ -763,15 +769,16 @@ handle_refresh_reveal_json (struct MHD_Connection *connection,
break; break;
for (j = 0; j < num_oldcoins; j++) for (j = 0; j < num_oldcoins; j++)
{ {
struct GNUNET_JSON_Specification tp_spec[] = {
GNUNET_JSON_spec_fixed_auto (NULL, &transfer_privs[i][j]),
GNUNET_JSON_spec_end ()
};
if (GNUNET_OK != res) if (GNUNET_OK != res)
break; break;
res = TMH_PARSE_navigate_json (connection, res = TMH_PARSE_json_array (connection,
tp_json, tp_json,
TMH_PARSE_JNC_INDEX, (int) i, tp_spec,
TMH_PARSE_JNC_INDEX, (int) j, i, j, -1);
TMH_PARSE_JNC_RET_DATA,
&transfer_privs[i][j],
sizeof (struct TALER_TransferPrivateKeyP));
GNUNET_break_op (GNUNET_OK == res); GNUNET_break_op (GNUNET_OK == res);
} }
} }
@ -817,10 +824,10 @@ TMH_REFRESH_handler_refresh_reveal (struct TMH_RequestHandler *rh,
json_t *reveal_detail; json_t *reveal_detail;
json_t *root; json_t *root;
json_t *transfer_privs; json_t *transfer_privs;
struct TMH_PARSE_FieldSpecification spec[] = { struct GNUNET_JSON_Specification spec[] = {
TMH_PARSE_member_fixed ("session_hash", &session_hash), GNUNET_JSON_spec_fixed_auto ("session_hash", &session_hash),
TMH_PARSE_member_array ("transfer_privs", &transfer_privs), GNUNET_JSON_spec_json ("transfer_privs", &transfer_privs),
TMH_PARSE_MEMBER_END GNUNET_JSON_spec_end ()
}; };
res = TMH_PARSE_post_json (connection, res = TMH_PARSE_post_json (connection,
@ -846,30 +853,25 @@ TMH_REFRESH_handler_refresh_reveal (struct TMH_RequestHandler *rh,
/* Note we do +1 as 1 row (cut-and-choose!) is missing! */ /* Note we do +1 as 1 row (cut-and-choose!) is missing! */
if (TALER_CNC_KAPPA != json_array_size (transfer_privs) + 1) if (TALER_CNC_KAPPA != json_array_size (transfer_privs) + 1)
{ {
TMH_PARSE_release_data (spec); GNUNET_JSON_parse_free (spec);
GNUNET_break_op (0); GNUNET_break_op (0);
return TMH_RESPONSE_reply_arg_invalid (connection, return TMH_RESPONSE_reply_arg_invalid (connection,
"transfer_privs"); "transfer_privs");
} }
res = TMH_PARSE_navigate_json (connection, reveal_detail = json_array_get (transfer_privs, 0);
transfer_privs, if (NULL == reveal_detail)
TMH_PARSE_JNC_INDEX, 0,
TMH_PARSE_JNC_RET_TYPED_JSON,
JSON_ARRAY,
&reveal_detail);
if (GNUNET_OK != res)
{ {
TMH_PARSE_release_data (spec); // FIXME: generate proper HTTP response!
GNUNET_JSON_parse_free (spec);
GNUNET_break_op (0); GNUNET_break_op (0);
return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
} }
num_oldcoins = json_array_size (reveal_detail); num_oldcoins = json_array_size (reveal_detail);
json_decref (reveal_detail);
res = handle_refresh_reveal_json (connection, res = handle_refresh_reveal_json (connection,
&session_hash, &session_hash,
num_oldcoins, num_oldcoins,
transfer_privs); transfer_privs);
TMH_PARSE_release_data (spec); GNUNET_JSON_parse_free (spec);
return res; return res;
} }

View File

@ -101,17 +101,17 @@ TMH_RESERVE_handler_reserve_withdraw (struct TMH_RequestHandler *rh,
struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki; struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
struct TMH_KS_StateHandle *ks; struct TMH_KS_StateHandle *ks;
struct TMH_PARSE_FieldSpecification spec[] = { struct GNUNET_JSON_Specification spec[] = {
TMH_PARSE_member_variable ("coin_ev", GNUNET_JSON_spec_varsize ("coin_ev",
(void **) &blinded_msg, (void **) &blinded_msg,
&blinded_msg_len), &blinded_msg_len),
TMH_PARSE_member_fixed ("reserve_pub", GNUNET_JSON_spec_fixed_auto ("reserve_pub",
&wsrd.reserve_pub), &wsrd.reserve_pub),
TMH_PARSE_member_fixed ("reserve_sig", GNUNET_JSON_spec_fixed_auto ("reserve_sig",
&signature), &signature),
TMH_PARSE_member_denomination_public_key ("denom_pub", TALER_JSON_spec_denomination_public_key ("denom_pub",
&denomination_pub), &denomination_pub),
TMH_PARSE_MEMBER_END GNUNET_JSON_spec_end ()
}; };
res = TMH_PARSE_post_json (connection, res = TMH_PARSE_post_json (connection,
@ -135,7 +135,7 @@ TMH_RESERVE_handler_reserve_withdraw (struct TMH_RequestHandler *rh,
TMH_KS_DKU_WITHDRAW); TMH_KS_DKU_WITHDRAW);
if (NULL == dki) if (NULL == dki)
{ {
TMH_PARSE_release_data (spec); GNUNET_JSON_parse_free (spec);
TMH_KS_release (ks); TMH_KS_release (ks);
return TMH_RESPONSE_reply_arg_unknown (connection, return TMH_RESPONSE_reply_arg_unknown (connection,
"denom_pub"); "denom_pub");
@ -169,7 +169,7 @@ TMH_RESERVE_handler_reserve_withdraw (struct TMH_RequestHandler *rh,
&wsrd.reserve_pub.eddsa_pub)) &wsrd.reserve_pub.eddsa_pub))
{ {
TALER_LOG_WARNING ("Client supplied invalid signature for /reserve/withdraw request\n"); TALER_LOG_WARNING ("Client supplied invalid signature for /reserve/withdraw request\n");
TMH_PARSE_release_data (spec); GNUNET_JSON_parse_free (spec);
return TMH_RESPONSE_reply_signature_invalid (connection, return TMH_RESPONSE_reply_signature_invalid (connection,
"reserve_sig"); "reserve_sig");
} }
@ -179,7 +179,7 @@ TMH_RESERVE_handler_reserve_withdraw (struct TMH_RequestHandler *rh,
blinded_msg, blinded_msg,
blinded_msg_len, blinded_msg_len,
&signature); &signature);
TMH_PARSE_release_data (spec); GNUNET_JSON_parse_free (spec);
return res; return res;
} }

View File

@ -63,9 +63,9 @@ TMH_TEST_handler_test_base32 (struct TMH_RequestHandler *rh,
void *in_ptr; void *in_ptr;
size_t in_ptr_size; size_t in_ptr_size;
struct GNUNET_HashCode hc; struct GNUNET_HashCode hc;
struct TMH_PARSE_FieldSpecification spec[] = { struct GNUNET_JSON_Specification spec[] = {
TMH_PARSE_member_variable ("input", &in_ptr, &in_ptr_size), GNUNET_JSON_spec_varsize ("input", &in_ptr, &in_ptr_size),
TMH_PARSE_MEMBER_END GNUNET_JSON_spec_end ()
}; };
res = TMH_PARSE_post_json (connection, res = TMH_PARSE_post_json (connection,
@ -85,7 +85,7 @@ TMH_TEST_handler_test_base32 (struct TMH_RequestHandler *rh,
GNUNET_CRYPTO_hash (in_ptr, GNUNET_CRYPTO_hash (in_ptr,
in_ptr_size, in_ptr_size,
&hc); &hc);
TMH_PARSE_release_data (spec); GNUNET_JSON_parse_free (spec);
json_decref (json); json_decref (json);
return TMH_RESPONSE_reply_json_pack (connection, return TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_OK, MHD_HTTP_OK,
@ -126,10 +126,10 @@ TMH_TEST_handler_test_encrypt (struct TMH_RequestHandler *rh,
struct GNUNET_CRYPTO_SymmetricSessionKey skey; struct GNUNET_CRYPTO_SymmetricSessionKey skey;
void *in_ptr; void *in_ptr;
size_t in_ptr_size; size_t in_ptr_size;
struct TMH_PARSE_FieldSpecification spec[] = { struct GNUNET_JSON_Specification spec[] = {
TMH_PARSE_member_variable ("input", &in_ptr, &in_ptr_size), GNUNET_JSON_spec_varsize ("input", &in_ptr, &in_ptr_size),
TMH_PARSE_member_fixed ("key_hash", &key), GNUNET_JSON_spec_fixed_auto ("key_hash", &key),
TMH_PARSE_MEMBER_END GNUNET_JSON_spec_end ()
}; };
char *out; char *out;
@ -168,7 +168,7 @@ TMH_TEST_handler_test_encrypt (struct TMH_RequestHandler *rh,
json = GNUNET_JSON_from_data (out, json = GNUNET_JSON_from_data (out,
in_ptr_size); in_ptr_size);
GNUNET_free (out); GNUNET_free (out);
TMH_PARSE_release_data (spec); GNUNET_JSON_parse_free (spec);
return TMH_RESPONSE_reply_json_pack (connection, return TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_OK, MHD_HTTP_OK,
"{s:o}", "{s:o}",
@ -206,9 +206,9 @@ TMH_TEST_handler_test_hkdf (struct TMH_RequestHandler *rh,
struct GNUNET_HashCode hc; struct GNUNET_HashCode hc;
void *in_ptr; void *in_ptr;
size_t in_ptr_size; size_t in_ptr_size;
struct TMH_PARSE_FieldSpecification spec[] = { struct GNUNET_JSON_Specification spec[] = {
TMH_PARSE_member_variable ("input", &in_ptr, &in_ptr_size), GNUNET_JSON_spec_varsize ("input", &in_ptr, &in_ptr_size),
TMH_PARSE_MEMBER_END GNUNET_JSON_spec_end ()
}; };
res = TMH_PARSE_post_json (connection, res = TMH_PARSE_post_json (connection,
@ -231,7 +231,7 @@ TMH_TEST_handler_test_hkdf (struct TMH_RequestHandler *rh,
in_ptr, in_ptr,
in_ptr_size, in_ptr_size,
NULL, 0); NULL, 0);
TMH_PARSE_release_data (spec); GNUNET_JSON_parse_free (spec);
json = GNUNET_JSON_from_data (&hc, json = GNUNET_JSON_from_data (&hc,
sizeof (struct GNUNET_HashCode)); sizeof (struct GNUNET_HashCode));
return TMH_RESPONSE_reply_json_pack (connection, return TMH_RESPONSE_reply_json_pack (connection,
@ -268,10 +268,10 @@ TMH_TEST_handler_test_ecdhe (struct TMH_RequestHandler *rh,
struct GNUNET_CRYPTO_EcdhePublicKey pub; struct GNUNET_CRYPTO_EcdhePublicKey pub;
struct GNUNET_CRYPTO_EcdhePrivateKey priv; struct GNUNET_CRYPTO_EcdhePrivateKey priv;
struct GNUNET_HashCode hc; struct GNUNET_HashCode hc;
struct TMH_PARSE_FieldSpecification spec[] = { struct GNUNET_JSON_Specification spec[] = {
TMH_PARSE_member_fixed ("ecdhe_pub", &pub), GNUNET_JSON_spec_fixed_auto ("ecdhe_pub", &pub),
TMH_PARSE_member_fixed ("ecdhe_priv", &priv), GNUNET_JSON_spec_fixed_auto ("ecdhe_priv", &priv),
TMH_PARSE_MEMBER_END GNUNET_JSON_spec_end ()
}; };
res = TMH_PARSE_post_json (connection, res = TMH_PARSE_post_json (connection,
@ -294,11 +294,11 @@ TMH_TEST_handler_test_ecdhe (struct TMH_RequestHandler *rh,
&pub, &pub,
&hc)) &hc))
{ {
TMH_PARSE_release_data (spec); GNUNET_JSON_parse_free (spec);
return TMH_RESPONSE_reply_internal_error (connection, return TMH_RESPONSE_reply_internal_error (connection,
"Failed to perform ECDH"); "Failed to perform ECDH");
} }
TMH_PARSE_release_data (spec); GNUNET_JSON_parse_free (spec);
return TMH_RESPONSE_reply_json_pack (connection, return TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_OK, MHD_HTTP_OK,
"{s:o}", "{s:o}",
@ -335,10 +335,10 @@ TMH_TEST_handler_test_eddsa (struct TMH_RequestHandler *rh,
struct GNUNET_CRYPTO_EddsaPublicKey pub; struct GNUNET_CRYPTO_EddsaPublicKey pub;
struct GNUNET_CRYPTO_EddsaSignature sig; struct GNUNET_CRYPTO_EddsaSignature sig;
struct GNUNET_CRYPTO_EccSignaturePurpose purpose; struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
struct TMH_PARSE_FieldSpecification spec[] = { struct GNUNET_JSON_Specification spec[] = {
TMH_PARSE_member_fixed ("eddsa_pub", &pub), GNUNET_JSON_spec_fixed_auto ("eddsa_pub", &pub),
TMH_PARSE_member_fixed ("eddsa_sig", &sig), GNUNET_JSON_spec_fixed_auto ("eddsa_sig", &sig),
TMH_PARSE_MEMBER_END GNUNET_JSON_spec_end ()
}; };
struct GNUNET_CRYPTO_EddsaPrivateKey *pk; struct GNUNET_CRYPTO_EddsaPrivateKey *pk;
@ -365,11 +365,11 @@ TMH_TEST_handler_test_eddsa (struct TMH_RequestHandler *rh,
&sig, &sig,
&pub)) &pub))
{ {
TMH_PARSE_release_data (spec); GNUNET_JSON_parse_free (spec);
return TMH_RESPONSE_reply_signature_invalid (connection, return TMH_RESPONSE_reply_signature_invalid (connection,
"eddsa_sig"); "eddsa_sig");
} }
TMH_PARSE_release_data (spec); GNUNET_JSON_parse_free (spec);
pk = GNUNET_CRYPTO_eddsa_key_create (); pk = GNUNET_CRYPTO_eddsa_key_create ();
purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_TEST_EDDSA); purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_TEST_EDDSA);
if (GNUNET_OK != if (GNUNET_OK !=
@ -466,9 +466,9 @@ TMH_TEST_handler_test_rsa_sign (struct TMH_RequestHandler *rh,
struct GNUNET_CRYPTO_rsa_Signature *sig; struct GNUNET_CRYPTO_rsa_Signature *sig;
void *in_ptr; void *in_ptr;
size_t in_ptr_size; size_t in_ptr_size;
struct TMH_PARSE_FieldSpecification spec[] = { struct GNUNET_JSON_Specification spec[] = {
TMH_PARSE_member_variable ("blind_ev", &in_ptr, &in_ptr_size), GNUNET_JSON_spec_varsize ("blind_ev", &in_ptr, &in_ptr_size),
TMH_PARSE_MEMBER_END GNUNET_JSON_spec_end ()
}; };
res = TMH_PARSE_post_json (connection, res = TMH_PARSE_post_json (connection,
@ -491,7 +491,7 @@ TMH_TEST_handler_test_rsa_sign (struct TMH_RequestHandler *rh,
if (NULL == rsa_pk) if (NULL == rsa_pk)
{ {
GNUNET_break (0); GNUNET_break (0);
TMH_PARSE_release_data (spec); GNUNET_JSON_parse_free (spec);
return TMH_RESPONSE_reply_internal_error (connection, return TMH_RESPONSE_reply_internal_error (connection,
"Failed to create RSA key"); "Failed to create RSA key");
} }
@ -501,11 +501,11 @@ TMH_TEST_handler_test_rsa_sign (struct TMH_RequestHandler *rh,
if (NULL == sig) if (NULL == sig)
{ {
GNUNET_break (0); GNUNET_break (0);
TMH_PARSE_release_data (spec); GNUNET_JSON_parse_free (spec);
return TMH_RESPONSE_reply_internal_error (connection, return TMH_RESPONSE_reply_internal_error (connection,
"Failed to RSA-sign"); "Failed to RSA-sign");
} }
TMH_PARSE_release_data (spec); GNUNET_JSON_parse_free (spec);
res = TMH_RESPONSE_reply_json_pack (connection, res = TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_OK, MHD_HTTP_OK,
"{s:o}", "{s:o}",
@ -542,11 +542,11 @@ TMH_TEST_handler_test_transfer (struct TMH_RequestHandler *rh,
struct TALER_EncryptedLinkSecretP secret_enc; struct TALER_EncryptedLinkSecretP secret_enc;
struct TALER_TransferPrivateKeyP trans_priv; struct TALER_TransferPrivateKeyP trans_priv;
struct TALER_CoinSpendPublicKeyP coin_pub; struct TALER_CoinSpendPublicKeyP coin_pub;
struct TMH_PARSE_FieldSpecification spec[] = { struct GNUNET_JSON_Specification spec[] = {
TMH_PARSE_member_fixed ("secret_enc", &secret_enc), GNUNET_JSON_spec_fixed_auto ("secret_enc", &secret_enc),
TMH_PARSE_member_fixed ("trans_priv", &trans_priv), GNUNET_JSON_spec_fixed_auto ("trans_priv", &trans_priv),
TMH_PARSE_member_fixed ("coin_pub", &coin_pub), GNUNET_JSON_spec_fixed_auto ("coin_pub", &coin_pub),
TMH_PARSE_MEMBER_END GNUNET_JSON_spec_end ()
}; };
struct TALER_LinkSecretP secret; struct TALER_LinkSecretP secret;
@ -571,7 +571,7 @@ TMH_TEST_handler_test_transfer (struct TMH_RequestHandler *rh,
&coin_pub, &coin_pub,
&secret)) &secret))
{ {
TMH_PARSE_release_data (spec); GNUNET_JSON_parse_free (spec);
return TMH_RESPONSE_reply_internal_error (connection, return TMH_RESPONSE_reply_internal_error (connection,
"Failed to decrypt secret"); "Failed to decrypt secret");
} }

View File

@ -121,14 +121,14 @@ TMH_TRACKING_handler_deposit_wtid (struct TMH_RequestHandler *rh,
struct TALER_DepositTrackPS tps; struct TALER_DepositTrackPS tps;
uint64_t transaction_id; uint64_t transaction_id;
struct TALER_MerchantSignatureP merchant_sig; struct TALER_MerchantSignatureP merchant_sig;
struct TMH_PARSE_FieldSpecification spec[] = { struct GNUNET_JSON_Specification spec[] = {
TMH_PARSE_member_fixed ("H_wire", &tps.h_wire), GNUNET_JSON_spec_fixed_auto ("H_wire", &tps.h_wire),
TMH_PARSE_member_fixed ("H_contract", &tps.h_contract), GNUNET_JSON_spec_fixed_auto ("H_contract", &tps.h_contract),
TMH_PARSE_member_fixed ("coin_pub", &tps.coin_pub), GNUNET_JSON_spec_fixed_auto ("coin_pub", &tps.coin_pub),
TMH_PARSE_member_uint64 ("transaction_id", &transaction_id), GNUNET_JSON_spec_uint64 ("transaction_id", &transaction_id),
TMH_PARSE_member_fixed ("merchant_pub", &tps.merchant), GNUNET_JSON_spec_fixed_auto ("merchant_pub", &tps.merchant),
TMH_PARSE_member_fixed ("merchant_sig", &merchant_sig), GNUNET_JSON_spec_fixed_auto ("merchant_sig", &merchant_sig),
TMH_PARSE_MEMBER_END GNUNET_JSON_spec_end ()
}; };
res = TMH_PARSE_post_json (connection, res = TMH_PARSE_post_json (connection,
@ -156,7 +156,7 @@ TMH_TRACKING_handler_deposit_wtid (struct TMH_RequestHandler *rh,
&tps.merchant, &tps.merchant,
&merchant_sig, &merchant_sig,
transaction_id); transaction_id);
TMH_PARSE_release_data (spec); GNUNET_JSON_parse_free (spec);
json_decref (json); json_decref (json);
return res; return res;
} }

View File

@ -57,6 +57,30 @@ TALER_JSON_spec_amount (const char *name,
struct TALER_Amount *r_amount); struct TALER_Amount *r_amount);
/**
* Generate line in parser specification for denomination public key.
*
* @param field name of the field
* @param[out] pk key to initialize
* @return corresponding field spec
*/
struct GNUNET_JSON_Specification
TALER_JSON_spec_denomination_public_key (const char *field,
struct TALER_DenominationPublicKey *pk);
/**
* Generate line in parser specification for denomination signature.
*
* @param field name of the field
* @param sig the signature to initialize
* @return corresponding field spec
*/
struct GNUNET_JSON_Specification
TALER_JSON_spec_denomination_signature (const char *field,
struct TALER_DenominationSignature *sig);
/** /**
* Hash a JSON for binary signing. * Hash a JSON for binary signing.
* *

View File

@ -143,4 +143,36 @@ TALER_JSON_spec_amount (const char *name,
} }
/**
* Generate line in parser specification for denomination public key.
*
* @param field name of the field
* @param[out] pk key to initialize
* @return corresponding field spec
*/
struct GNUNET_JSON_Specification
TALER_JSON_spec_denomination_public_key (const char *field,
struct TALER_DenominationPublicKey *pk)
{
return GNUNET_JSON_spec_rsa_public_key (field,
&pk->rsa_public_key);
}
/**
* Generate line in parser specification for denomination signature.
*
* @param field name of the field
* @param sig the signature to initialize
* @return corresponding field spec
*/
struct GNUNET_JSON_Specification
TALER_JSON_spec_denomination_signature (const char *field,
struct TALER_DenominationSignature *sig)
{
return GNUNET_JSON_spec_rsa_signature (field,
&sig->rsa_signature);
}
/* end of json/json_helper.c */ /* end of json/json_helper.c */