diff options
author | Christian Blättler <blatc2@bfh.ch> | 2024-04-21 16:05:20 +0200 |
---|---|---|
committer | Christian Blättler <blatc2@bfh.ch> | 2024-04-21 16:05:20 +0200 |
commit | fa4322c49ca1d768bb9c6bb75436fab89d75e623 (patch) | |
tree | 7f9d39c04b4178f62bc5045c1bb1d9da4cdda744 /src/backend/taler-merchant-httpd_contract.c | |
parent | e3965464791470843660ccf2f54fced53ffffcdf (diff) |
work on pay handler
Diffstat (limited to 'src/backend/taler-merchant-httpd_contract.c')
-rw-r--r-- | src/backend/taler-merchant-httpd_contract.c | 150 |
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 |