summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-06-20 22:40:06 +0200
committerChristian Grothoff <christian@grothoff.org>2015-06-20 22:40:06 +0200
commit61752e033436d73c7a70bc12d5be4706f1595ab6 (patch)
tree459abddec65b460ce4b1473ed96d8a5df3d6ed21
parente2d453f1d2c9db904f2d3dc3146c7fc3f2565bef (diff)
downloadexchange-61752e033436d73c7a70bc12d5be4706f1595ab6.tar.gz
exchange-61752e033436d73c7a70bc12d5be4706f1595ab6.tar.bz2
exchange-61752e033436d73c7a70bc12d5be4706f1595ab6.zip
simplify /keys parser by using json parser interpreter
-rw-r--r--src/mint-lib/mint_api_handle.c261
-rw-r--r--src/mint-lib/mint_api_json.c129
-rw-r--r--src/mint-lib/mint_api_json.h66
-rw-r--r--src/util/json.c6
4 files changed, 243 insertions, 219 deletions
diff --git a/src/mint-lib/mint_api_handle.c b/src/mint-lib/mint_api_handle.c
index bd7d00e6..8a5212ae 100644
--- a/src/mint-lib/mint_api_handle.c
+++ b/src/mint-lib/mint_api_handle.c
@@ -27,6 +27,7 @@
#include "taler_mint_service.h"
#include "taler_signatures.h"
#include "mint_api_context.h"
+#include "mint_api_json.h"
#include "mint_api_handle.h"
@@ -229,29 +230,6 @@ free_keys_request (struct KeysRequest *kr)
}
-/**
- * Parses the timestamp encoded as ASCII string as UNIX timstamp.
- * FIXME: we might want to move this function into libtalerutil.
- *
- * @param[out] abs successfully parsed timestamp will be returned thru this parameter
- * @param tstamp_enc the ASCII encoding of the timestamp
- * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
- */
-static int
-parse_timestamp (struct GNUNET_TIME_Absolute *abs,
- const char *tstamp_enc)
-{
- unsigned long tstamp;
-
- if (1 != sscanf (tstamp_enc, "%lu", &tstamp))
- return GNUNET_SYSERR;
- *abs = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get_zero_ (),
- GNUNET_TIME_relative_multiply
- (GNUNET_TIME_UNIT_SECONDS, tstamp));
- return GNUNET_OK;
-}
-
-
#define EXITIF(cond) \
do { \
if (cond) { GNUNET_break (0); goto EXITIF_exit; } \
@@ -272,110 +250,55 @@ parse_json_signkey (struct TALER_MINT_SigningPublicKey *sign_key,
json_t *sign_key_obj,
const struct TALER_MasterPublicKeyP *master_key)
{
- // TODO: try to simplify...
- json_t *valid_from_obj;
- json_t *valid_until_obj;
- json_t *valid_legal_obj;
- json_t *key_obj;
- json_t *sig_obj;
- const char *valid_from_enc;
- const char *valid_until_enc;
- const char *valid_legal_enc;
- const char *key_enc;
- const char *sig_enc;
struct TALER_MintSigningKeyValidityPS sign_key_issue;
struct GNUNET_CRYPTO_EddsaSignature sig;
struct GNUNET_TIME_Absolute valid_from;
struct GNUNET_TIME_Absolute valid_until;
struct GNUNET_TIME_Absolute valid_legal;
+ struct MAJ_Specification spec[] = {
+ MAJ_spec_fixed_auto ("master_sig",
+ &sig),
+ MAJ_spec_fixed_auto ("key",
+ &sign_key_issue.signkey_pub),
+ MAJ_spec_absolute_time ("stamp_start",
+ &valid_from),
+ MAJ_spec_absolute_time ("stamp_expire",
+ &valid_until),
+ MAJ_spec_absolute_time ("stamp_end",
+ &valid_legal),
+ MAJ_spec_end
+ };
+
+ if (GNUNET_OK !=
+ MAJ_parse_json (sign_key_obj,
+ spec))
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
- EXITIF (JSON_OBJECT != json_typeof (sign_key_obj));
- EXITIF (NULL == (valid_from_obj = json_object_get (sign_key_obj,
- "stamp_start")));
- EXITIF (NULL == (valid_until_obj = json_object_get (sign_key_obj,
- "stamp_expire")));
- EXITIF (NULL == (valid_legal_obj = json_object_get (sign_key_obj,
- "stamp_end")));
- EXITIF (NULL == (key_obj = json_object_get (sign_key_obj, "key")));
- EXITIF (NULL == (sig_obj = json_object_get (sign_key_obj, "master_sig")));
- EXITIF (NULL == (valid_from_enc = json_string_value (valid_from_obj)));
- EXITIF (NULL == (valid_until_enc = json_string_value (valid_until_obj)));
- EXITIF (NULL == (valid_legal_enc = json_string_value (valid_legal_obj)));
- EXITIF (NULL == (key_enc = json_string_value (key_obj)));
- EXITIF (NULL == (sig_enc = json_string_value (sig_obj)));
- EXITIF (GNUNET_SYSERR == parse_timestamp (&valid_from,
- valid_from_enc));
- EXITIF (GNUNET_SYSERR == parse_timestamp (&valid_until,
- valid_until_enc));
- EXITIF (GNUNET_SYSERR == parse_timestamp (&valid_legal,
- valid_legal_enc));
- EXITIF (52 != strlen (key_enc)); /* strlen(base32(char[32])) = 52 */
- EXITIF (103 != strlen (sig_enc)); /* strlen(base32(char[64])) = 103 */
- EXITIF (GNUNET_OK != GNUNET_STRINGS_string_to_data (sig_enc, 103,
- &sig, sizeof (sig)));
- memset (&sign_key_issue,
- 0,
- sizeof (sign_key_issue));
- EXITIF (GNUNET_SYSERR ==
- GNUNET_CRYPTO_eddsa_public_key_from_string (key_enc,
- 52,
- &sign_key_issue.signkey_pub.eddsa_pub));
sign_key_issue.purpose.purpose = htonl (TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY);
sign_key_issue.purpose.size =
htonl (sizeof (sign_key_issue)
- - offsetof (struct TALER_MintSigningKeyValidityPS, purpose));
+ - offsetof (struct TALER_MintSigningKeyValidityPS,
+ purpose));
sign_key_issue.master_public_key = *master_key;
sign_key_issue.start = GNUNET_TIME_absolute_hton (valid_from);
sign_key_issue.expire = GNUNET_TIME_absolute_hton (valid_until);
sign_key_issue.end = GNUNET_TIME_absolute_hton (valid_legal);
- EXITIF (GNUNET_OK !=
- GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY,
- &sign_key_issue.purpose,
- &sig,
- &master_key->eddsa_pub));
+ if (GNUNET_OK !=
+ GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY,
+ &sign_key_issue.purpose,
+ &sig,
+ &master_key->eddsa_pub))
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
sign_key->valid_from = valid_from;
sign_key->valid_until = valid_until;
sign_key->key = sign_key_issue.signkey_pub;
return GNUNET_OK;
-
- EXITIF_exit:
- return GNUNET_SYSERR;
-}
-
-
-/**
- * Parse an amount given in JSON encoding.
- *
- * @param[in] amount_obj the amount in json
- * @param[out] where to return the parsed amount
- * @return #GNUNET_OK if all is well, #GNUNET_SYSERR on parse errors
- */
-static int
-parse_json_amount (json_t *amount_obj,
- struct TALER_Amount *amt)
-{
- // FIXME: check for correctness...
- json_t *obj;
- const char *currency_str;
- int value; // FIXME: bad data type! (64 bit!)
- int fraction;
-
- EXITIF (NULL == (obj = json_object_get (amount_obj, "currency")));
- EXITIF (NULL == (currency_str = json_string_value (obj)));
- EXITIF (NULL == (obj = json_object_get (amount_obj, "value")));
- EXITIF (JSON_INTEGER != json_typeof (obj));
- EXITIF (0 > (value = json_integer_value (obj)));
- EXITIF (NULL == (obj = json_object_get (amount_obj, "fraction")));
- EXITIF (JSON_INTEGER != json_typeof (obj));
- EXITIF (0 > (fraction = json_integer_value (obj)));
- (void) memset (amt->currency, 0, sizeof (amt->currency));
- (void) strncpy (amt->currency, currency_str, sizeof (amt->currency) - 1);
- amt->value = (uint32_t) value;
- amt->fraction = (uint32_t) fraction;
- return GNUNET_OK;
-
- EXITIF_exit:
- return GNUNET_SYSERR;
}
@@ -393,16 +316,6 @@ parse_json_denomkey (struct TALER_MINT_DenomPublicKey *denom_key,
json_t *denom_key_obj,
struct TALER_MasterPublicKeyP *master_key)
{
- // FIXME: check logic, try to simplify
- json_t *obj;
- const char *sig_enc;
- const char *deposit_valid_until_enc;
- const char *withdraw_valid_until_enc;
- const char *valid_from_enc;
- const char *expire_legal_enc;
- const char *key_enc;
- char *buf;
- size_t buf_size;
struct GNUNET_TIME_Absolute valid_from;
struct GNUNET_TIME_Absolute withdraw_valid_until;
struct GNUNET_TIME_Absolute deposit_valid_until;
@@ -415,55 +328,38 @@ parse_json_denomkey (struct TALER_MINT_DenomPublicKey *denom_key,
struct GNUNET_CRYPTO_rsa_PublicKey *pk;
struct GNUNET_CRYPTO_EddsaSignature sig;
- EXITIF (JSON_OBJECT != json_typeof (denom_key_obj));
- EXITIF (NULL == (obj = json_object_get (denom_key_obj, "master_sig")));
- EXITIF (NULL == (sig_enc = json_string_value (obj)));
- EXITIF (103 != strlen (sig_enc));
- EXITIF (GNUNET_OK != GNUNET_STRINGS_string_to_data (sig_enc, 103,
- &sig, sizeof (sig)));
- EXITIF (NULL == (obj = json_object_get (denom_key_obj, "stamp_expire_deposit")));
- EXITIF (NULL == (deposit_valid_until_enc = json_string_value (obj)));
- EXITIF (NULL == (obj = json_object_get (denom_key_obj, "stamp_expire_withdraw")));
- EXITIF (NULL == (withdraw_valid_until_enc = json_string_value (obj)));
- EXITIF (NULL == (obj = json_object_get (denom_key_obj, "stamp_start")));
- EXITIF (NULL == (valid_from_enc = json_string_value (obj)));
- EXITIF (NULL == (obj = json_object_get (denom_key_obj, "stamp_expire_legal")));
- EXITIF (NULL == (expire_legal_enc = json_string_value (obj)));
-
- EXITIF (NULL == (obj = json_object_get (denom_key_obj, "denom_pub")));
- EXITIF (NULL == (key_enc = json_string_value (obj)));
-
- EXITIF (GNUNET_SYSERR == parse_timestamp (&valid_from, valid_from_enc));
- EXITIF (GNUNET_SYSERR == parse_timestamp (&withdraw_valid_until,
- withdraw_valid_until_enc));
- EXITIF (GNUNET_SYSERR == parse_timestamp (&deposit_valid_until,
- deposit_valid_until_enc));
- EXITIF (GNUNET_SYSERR == parse_timestamp (&expire_legal,
- expire_legal_enc));
+ struct MAJ_Specification spec[] = {
+ MAJ_spec_fixed_auto ("master_sig",
+ &sig),
+ MAJ_spec_absolute_time ("stamp_expire_deposit",
+ &deposit_valid_until),
+ MAJ_spec_absolute_time ("stamp_expire_withdraw",
+ &withdraw_valid_until),
+ MAJ_spec_absolute_time ("stamp_start",
+ &valid_from),
+ MAJ_spec_absolute_time ("stamp_expire_legal",
+ &expire_legal),
+ MAJ_spec_amount ("value",
+ &value),
+ MAJ_spec_amount ("fee_withdraw",
+ &fee_withdraw),
+ MAJ_spec_amount ("fee_deposit",
+ &fee_deposit),
+ MAJ_spec_amount ("fee_refresh",
+ &fee_refresh),
+ MAJ_spec_rsa_public_key ("denom_pub",
+ &pk),
+ MAJ_spec_end
+ };
+
+ if (GNUNET_OK !=
+ MAJ_parse_json (denom_key_obj,
+ spec))
+ return GNUNET_SYSERR;
memset (&denom_key_issue, 0, sizeof (denom_key_issue));
-
- buf_size = (strlen (key_enc) * 5) / 8;
- buf = GNUNET_malloc (buf_size);
-
- EXITIF (GNUNET_OK !=
- GNUNET_STRINGS_string_to_data (key_enc, strlen (key_enc),
- buf,
- buf_size));
- pk = GNUNET_CRYPTO_rsa_public_key_decode (buf, buf_size);
- GNUNET_free (buf);
-
- EXITIF (NULL == pk);
GNUNET_CRYPTO_rsa_public_key_hash (pk,
&denom_key_issue.denom_hash);
- EXITIF (NULL == (obj = json_object_get (denom_key_obj, "value")));
- EXITIF (GNUNET_SYSERR == parse_json_amount (obj, &value));
- EXITIF (NULL == (obj = json_object_get (denom_key_obj, "fee_withdraw")));
- EXITIF (GNUNET_SYSERR == parse_json_amount (obj, &fee_withdraw));
- EXITIF (NULL == (obj = json_object_get (denom_key_obj, "fee_deposit")));
- EXITIF (GNUNET_SYSERR == parse_json_amount (obj, &fee_deposit));
- EXITIF (NULL == (obj = json_object_get (denom_key_obj, "fee_refresh")));
- EXITIF (GNUNET_SYSERR == parse_json_amount (obj, &fee_refresh));
denom_key_issue.purpose.purpose
= htonl (TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY);
denom_key_issue.purpose.size
@@ -499,6 +395,7 @@ parse_json_denomkey (struct TALER_MINT_DenomPublicKey *denom_key,
return GNUNET_OK;
EXITIF_exit:
+ MAJ_parse_free (spec);
return GNUNET_SYSERR;
}
@@ -520,33 +417,19 @@ decode_keys_json (json_t *resp_obj,
if (JSON_OBJECT != json_typeof (resp_obj))
return GNUNET_SYSERR;
- /* parse the master public key */
+ /* parse the master public key and issue date of the response */
{
- json_t *master_key_obj;
- const char *master_key_enc;
+ struct MAJ_Specification spec[] = {
+ MAJ_spec_fixed_auto ("master_public_key",
+ &key_data->master_pub),
+ MAJ_spec_absolute_time ("list_issue_date",
+ &list_issue_date),
+ MAJ_spec_end
+ };
- EXITIF (NULL == (master_key_obj =
- json_object_get (resp_obj,
- "master_public_key")));
- EXITIF (NULL == (master_key_enc =
- json_string_value (master_key_obj)));
EXITIF (GNUNET_OK !=
- GNUNET_CRYPTO_eddsa_public_key_from_string (master_key_enc,
- strlen (master_key_enc),
- &key_data->master_pub.eddsa_pub));
- }
-
- /* parse the issue date of the response */
- {
- json_t *list_issue_date_obj;
- const char *tstamp_enc;
-
- EXITIF (NULL == (list_issue_date_obj =
- json_object_get (resp_obj,
- "list_issue_date")));
- EXITIF (NULL == (tstamp_enc = json_string_value (list_issue_date_obj)));
- EXITIF (GNUNET_SYSERR == parse_timestamp (&list_issue_date,
- tstamp_enc));
+ MAJ_parse_json (resp_obj,
+ spec));
}
/* parse the signing keys */
diff --git a/src/mint-lib/mint_api_json.c b/src/mint-lib/mint_api_json.c
index b2757f11..75010a4d 100644
--- a/src/mint-lib/mint_api_json.c
+++ b/src/mint-lib/mint_api_json.c
@@ -72,9 +72,9 @@ parse_time_abs (json_t *f,
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
- /* Time is in 'ms' in JSON, but in microseconds in GNUNET_TIME_Absolute */
- time->abs_value_us = tval * 1000LL;
- if ( (time->abs_value_us) / 1000LL != tval)
+ /* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Absolute */
+ time->abs_value_us = tval * 1000LL * 1000LL;
+ if ( (time->abs_value_us) / 1000LL / 1000LL != tval)
{
/* Integer overflow */
GNUNET_break_op (0);
@@ -189,7 +189,7 @@ parse_json (json_t *root,
}
res = GNUNET_STRINGS_string_to_data (str, strlen (str),
spec[i].details.fixed_data.dest,
- spec[i].details.fixed_data.dest_len);
+ spec[i].details.fixed_data.dest_size);
if (GNUNET_OK != res)
{
GNUNET_break_op (0);
@@ -201,7 +201,7 @@ parse_json (json_t *root,
case MAJ_CMD_BINARY_VARIABLE:
{
const char *str;
- size_t len;
+ size_t size;
void *data;
int res;
@@ -211,16 +211,17 @@ parse_json (json_t *root,
GNUNET_break_op (0);
return i;
}
- len = (strlen (str) * 5) / 8;
- if (len >= 1024)
+ size = (strlen (str) * 5) / 8;
+ if (size >= 1024)
{
GNUNET_break_op (0);
return i;
}
- data = GNUNET_malloc (len);
- res = GNUNET_STRINGS_string_to_data (str, strlen (str),
+ data = GNUNET_malloc (size);
+ res = GNUNET_STRINGS_string_to_data (str,
+ strlen (str),
data,
- len);
+ size);
if (GNUNET_OK != res)
{
GNUNET_break_op (0);
@@ -228,13 +229,13 @@ parse_json (json_t *root,
return i;
}
*spec[i].details.variable_data.dest_p = data;
- *spec[i].details.variable_data.dest_len_p = len;
+ *spec[i].details.variable_data.dest_size_p = size;
}
break;
case MAJ_CMD_RSA_PUBLIC_KEY:
{
- size_t len;
+ size_t size;
const char *str;
int res;
void *buf;
@@ -245,12 +246,12 @@ parse_json (json_t *root,
GNUNET_break_op (0);
return i;
}
- len = (strlen (str) * 5) / 8;
- buf = GNUNET_malloc (len);
+ size = (strlen (str) * 5) / 8;
+ buf = GNUNET_malloc (size);
res = GNUNET_STRINGS_string_to_data (str,
strlen (str),
buf,
- len);
+ size);
if (GNUNET_OK != res)
{
GNUNET_free (buf);
@@ -259,7 +260,7 @@ parse_json (json_t *root,
}
*spec[i].details.rsa_public_key
= GNUNET_CRYPTO_rsa_public_key_decode (buf,
- len);
+ size);
GNUNET_free (buf);
if (NULL == spec[i].details.rsa_public_key)
{
@@ -271,7 +272,7 @@ parse_json (json_t *root,
case MAJ_CMD_RSA_SIGNATURE:
{
- size_t len;
+ size_t size;
const char *str;
int res;
void *buf;
@@ -282,12 +283,12 @@ parse_json (json_t *root,
GNUNET_break_op (0);
return i;
}
- len = (strlen (str) * 5) / 8;
- buf = GNUNET_malloc (len);
+ size = (strlen (str) * 5) / 8;
+ buf = GNUNET_malloc (size);
res = GNUNET_STRINGS_string_to_data (str,
strlen (str),
buf,
- len);
+ size);
if (GNUNET_OK != res)
{
GNUNET_free (buf);
@@ -296,7 +297,7 @@ parse_json (json_t *root,
}
*spec[i].details.rsa_signature
= GNUNET_CRYPTO_rsa_signature_decode (buf,
- len);
+ size);
GNUNET_free (buf);
if (NULL == spec[i].details.rsa_signature)
return i;
@@ -341,7 +342,7 @@ parse_free (struct MAJ_Specification *spec,
case MAJ_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_len_p = 0;
+ *spec[i].details.variable_data.dest_size_p = 0;
break;
case MAJ_CMD_RSA_PUBLIC_KEY:
GNUNET_CRYPTO_rsa_public_key_free (*spec[i].details.rsa_public_key);
@@ -377,8 +378,9 @@ MAJ_parse_json (const json_t *root,
if (-1 == ret)
return GNUNET_OK;
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "JSON field `%s` had unexpected value\n",
- spec[ret].field);
+ "JSON field `%s` (%d) had unexpected value\n",
+ spec[ret].field,
+ ret);
parse_free (spec, ret);
return GNUNET_SYSERR;
}
@@ -400,5 +402,84 @@ MAJ_parse_free (struct MAJ_Specification *spec)
}
+/**
+ * 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 MAJ_Specification
+MAJ_spec_absolute_time (const char *name,
+ struct GNUNET_TIME_Absolute *at)
+{
+ struct MAJ_Specification ret =
+ {
+ .cmd = MAJ_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 at where to store the absolute time found under @a name
+ */
+struct MAJ_Specification
+MAJ_spec_amount (const char *name,
+ struct TALER_Amount *amount)
+{
+ struct MAJ_Specification ret =
+ {
+ .cmd = MAJ_CMD_AMOUNT,
+ .field = name,
+ .details.amount = amount
+ };
+ 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 MAJ_Specification
+MAJ_spec_rsa_public_key (const char *name,
+ struct GNUNET_CRYPTO_rsa_PublicKey **pk)
+{
+ struct MAJ_Specification ret =
+ {
+ .cmd = MAJ_CMD_AMOUNT,
+ .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 MAJ_Specification
+MAJ_spec_rsa_signature (const char *name,
+ struct GNUNET_CRYPTO_rsa_Signature **sig)
+{
+ struct MAJ_Specification ret =
+ {
+ .cmd = MAJ_CMD_AMOUNT,
+ .field = name,
+ .details.rsa_signature = sig
+ };
+ return ret;
+}
+
/* end of mint_api_json.c */
diff --git a/src/mint-lib/mint_api_json.h b/src/mint-lib/mint_api_json.h
index 87afbd44..78107ed9 100644
--- a/src/mint-lib/mint_api_json.h
+++ b/src/mint-lib/mint_api_json.h
@@ -129,7 +129,7 @@ struct MAJ_Specification
/**
* How many bytes to write to @e dest.
*/
- size_t dest_len;
+ size_t dest_size;
} fixed_data;
@@ -145,7 +145,7 @@ struct MAJ_Specification
/**
* Where to store the number of bytes allocated at `*dest`.
*/
- size_t *dest_len_p;
+ size_t *dest_size_p;
} variable_data;
@@ -164,7 +164,6 @@ struct MAJ_Specification
};
-
/**
* Navigate and parse data in a JSON tree.
*
@@ -187,4 +186,65 @@ void
MAJ_parse_free (struct MAJ_Specification *spec);
+/**
+ * End of a parser specification.
+ */
+#define MAJ_spec_end { .cmd = MAJ_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 MAJ_spec_fixed_auto(name,obj) { .cmd = MAJ_CMD_BINARY_FIXED, .field = name, .details.fixed_data.dest = obj, .details.fixed_data.dest_size = sizeof (*obj) }
+
+
+/**
+ * Absolute time.
+ *
+ * @param name name of the JSON field
+ * @param at where to store the absolute time found under @a name
+ */
+struct MAJ_Specification
+MAJ_spec_absolute_time (const char *name,
+ struct GNUNET_TIME_Absolute *at);
+
+
+/**
+ * Specification for parsing an amount value.
+ *
+ * @param name name of the JSON field
+ * @param at where to store the absolute time found under @a name
+ */
+struct MAJ_Specification
+MAJ_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 MAJ_Specification
+MAJ_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 MAJ_Specification
+MAJ_spec_rsa_signature (const char *name,
+ struct GNUNET_CRYPTO_rsa_Signature **sig);
+
+
+
+
/* end of mint_api_json.h */
diff --git a/src/util/json.c b/src/util/json.c
index e35b88a8..d72840eb 100644
--- a/src/util/json.c
+++ b/src/util/json.c
@@ -92,8 +92,8 @@ TALER_json_from_abs (struct GNUNET_TIME_Absolute stamp)
if (stamp.abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us)
return json_string ("never");
ret = GNUNET_asprintf (&mystr,
- "%llu",
- (long long) (stamp.abs_value_us / (1000 * 1000)));
+ "/%llu/",
+ (long long) (stamp.abs_value_us / (1000LL * 1000LL)));
GNUNET_assert (ret > 0);
j = json_string (mystr);
GNUNET_free (mystr);
@@ -330,7 +330,7 @@ TALER_json_to_abs (json_t *json,
return GNUNET_OK;
}
EXITIF (1 > sscanf (str, "%llu", &abs_value_s));
- abs->abs_value_us = abs_value_s * 1000 * 1000;
+ abs->abs_value_us = abs_value_s * 1000LL * 1000LL;
return GNUNET_OK;
EXITIF_exit: