aboutsummaryrefslogtreecommitdiff
path: root/src/backend/taler-merchant-httpd_contract.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/taler-merchant-httpd_contract.c')
-rw-r--r--src/backend/taler-merchant-httpd_contract.c150
1 files changed, 148 insertions, 2 deletions
diff --git a/src/backend/taler-merchant-httpd_contract.c b/src/backend/taler-merchant-httpd_contract.c
index 60f45776..6e98f56f 100644
--- a/src/backend/taler-merchant-httpd_contract.c
+++ b/src/backend/taler-merchant-httpd_contract.c
@@ -19,7 +19,9 @@
* @author Christian Blättler
*/
#include "platform.h"
+#include <gnunet/gnunet_common.h>
#include <jansson.h>
+#include <stdint.h>
#include "taler-merchant-httpd_contract.h"
enum TALER_MerchantContractInputType
@@ -83,7 +85,7 @@ TMH_string_from_contract_output_type (enum TALER_MerchantContractOutputType t)
* @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
*/
static enum GNUNET_GenericReturnValue
-parse_choice (void *cls,
+parse_choices (void *cls,
json_t *root,
struct GNUNET_JSON_Specification *spec)
{
@@ -263,10 +265,154 @@ TALER_JSON_spec_choices (const char *name,
{
struct GNUNET_JSON_Specification ret = {
.cls = (void *) choices_len,
- .parser = &parse_choice,
+ .parser = &parse_choices,
.field = name,
.ptr = choices,
};
return ret;
+}
+
+
+/**
+ * Parse given JSON object to token families array.
+ *
+ * @param cls closure, pointer to array length
+ * @param root the json object representing the token families. The keys are
+ * the token family slugs.
+ * @param[out] spec where to write the data
+ * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
+ */
+static enum GNUNET_GenericReturnValue
+parse_token_families (void *cls,
+ json_t *root,
+ struct GNUNET_JSON_Specification *spec)
+{
+ struct TALER_MerchantContractTokenFamily **families = spec->ptr;
+ unsigned int *families_len = cls;
+ json_t *jfamily;
+ const char *slug;
+ if (!json_is_object (root))
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+
+ json_object_foreach(root, slug, jfamily)
+ {
+ const json_t *keys;
+ struct TALER_MerchantContractTokenFamily family = {
+ .slug = slug
+ };
+
+ struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_array_const ("keys",
+ &keys),
+ GNUNET_JSON_spec_bool ("critical",
+ &family.critical),
+ /* TODO: Figure out if these fields should be 'const' */
+ // GNUNET_JSON_spec_string ("description",
+ // &family.description),
+ // GNUNET_JSON_spec_object_const ("description_i18n",
+ // &family.description_i18n),
+ };
+ const char *error_name;
+ unsigned int error_line;
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (jfamily,
+ spec,
+ &error_name,
+ &error_line))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Failed to parse %s at %u: %s\n",
+ spec[error_line].field,
+ error_line,
+ error_name);
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+
+ GNUNET_array_grow (family.keys,
+ family.keys_len,
+ json_array_size (keys));
+
+ for (unsigned int i = 0; i<family.keys_len; i++)
+ {
+ /* TODO: Move this to TALER_JSON_spec_token_issue_key */
+ int64_t cipher;
+ struct TALER_MerchantContractTokenFamilyKey key;
+ key = family.keys[i];
+ /* TODO: Free when not used anymore */
+ key.pub.public_key = GNUNET_new (struct GNUNET_CRYPTO_BlindSignPublicKey);
+ struct GNUNET_JSON_Specification key_spec[] = {
+ GNUNET_JSON_spec_fixed_auto ("h_pub",
+ &key.pub.public_key->pub_key_hash),
+ GNUNET_JSON_spec_rsa_public_key ("rsa_pub",
+ &key.pub.public_key->details.rsa_public_key),
+ // GNUNET_JSON_spec_fixed_auto ("cs_pub",
+ // &key.pub.public_key->details.cs_public_key)),
+ GNUNET_JSON_spec_int64 ("cipher",
+ &cipher),
+ GNUNET_JSON_spec_timestamp ("valid_after",
+ &key.valid_after),
+ GNUNET_JSON_spec_timestamp ("valid_before",
+ &key.valid_before),
+ GNUNET_JSON_spec_end()
+ };
+ const char *ierror_name;
+ unsigned int ierror_line;
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (json_array_get (keys, i),
+ key_spec,
+ &ierror_name,
+ &ierror_line))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Failed to parse %s at %u: %s\n",
+ key_spec[ierror_line].field,
+ ierror_line,
+ ierror_name);
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+
+ switch (cipher) {
+ case GNUNET_CRYPTO_BSA_RSA:
+ key.pub.public_key->cipher = GNUNET_CRYPTO_BSA_RSA;
+ break;
+ case GNUNET_CRYPTO_BSA_CS:
+ key.pub.public_key->cipher = GNUNET_CRYPTO_BSA_CS;
+ break;
+ case GNUNET_CRYPTO_BSA_INVALID:
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Field 'cipher' invalid in key #%u\n",
+ i);
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ }
+
+ GNUNET_array_append (*families, *families_len, family);
+ }
+
+ return GNUNET_OK;
+}
+
+
+struct GNUNET_JSON_Specification
+TALER_JSON_spec_token_families (const char *name,
+ struct TALER_MerchantContractTokenFamily **families,
+ unsigned int *families_len)
+{
+ struct GNUNET_JSON_Specification ret = {
+ .cls = (void *) families_len,
+ .parser = &parse_token_families,
+ .field = name,
+ .ptr = families,
+ };
+
+ return ret;
} \ No newline at end of file