donau

Donation authority for GNU Taler (experimental)
Log | Files | Refs | Submodules | README | LICENSE

commit 8b4e454a80884150c46ce939d461244530c0d350
parent 7c3dc032bf5af4d007180ec736a383fcae2e98a8
Author: Casaburi Johannes <johannes.casaburi@students.bfh.ch>
Date:   Wed, 20 Mar 2024 17:26:29 +0100

changes and cleanup in keys and json

Diffstat:
Msrc/donau/Makefile.am | 1+
Msrc/donau/donau-httpd.c | 4++--
Msrc/donau/donau-httpd_keys.c | 276+++++++++++++++++++++++++------------------------------------------------------
Msrc/include/Makefile.am | 4++--
Msrc/include/donau_json_lib.h | 13+++++++++++++
Msrc/json/json_helper.c | 620-------------------------------------------------------------------------------
Msrc/json/json_pack.c | 263+------------------------------------------------------------------------------
7 files changed, 109 insertions(+), 1072 deletions(-)

diff --git a/src/donau/Makefile.am b/src/donau/Makefile.am @@ -23,6 +23,7 @@ donau_httpd_LDADD = \ $(LIBGCRYPT_LIBS) \ $(top_builddir)/src/donaudb/libdonaudb.la \ $(top_builddir)/src/util/libdonauutil.la \ + $(top_builddir)/src/json/libdonaujson.la \ -lmicrohttpd \ -ltalermhd \ -ltalerutil \ diff --git a/src/donau/donau-httpd.c b/src/donau/donau-httpd.c @@ -27,10 +27,10 @@ #include <sched.h> #include <sys/resource.h> #include <limits.h> -// #include <taler/taler_templating_lib.h> #include <taler/taler_mhd_lib.h> #include "donaudb_lib.h" #include "donau_util.h" +#include "donau_json_lib.h" #include "donau-httpd_config.h" #include "donau-httpd_keys.h" #include "donau-httpd_charity.h" @@ -497,7 +497,7 @@ handle_mhd_request (void *cls, .nargs = 1, .nargs_is_upper_bound = true }, - /* POST batch issue receipts */ + /* POST batch issue receipts */ { .url = "batch-issue", .method = MHD_HTTP_METHOD_POST, diff --git a/src/donau/donau-httpd_keys.c b/src/donau/donau-httpd_keys.c @@ -24,6 +24,7 @@ #include <taler/platform.h> #include <taler/taler_json_lib.h> #include <taler/taler_mhd_lib.h> +#include "donau_json_lib.h" #include "donau-httpd.h" #include "donau-httpd_keys.h" #include "donau-httpd_config.h" @@ -116,95 +117,6 @@ static struct TALER_SecurityModulePublicKeyP donation_unit_cs_sm_pub; */ static struct TALER_SecurityModulePublicKeyP esign_sm_pub; - -/** - * Information about a donation unit on offer by the donation unit helper. - */ -// KILL! -struct HelperDonationUnit -{ - - /** - * When will the helper start to use this key for signing? - */ - struct GNUNET_TIME_Timestamp start_time; - - /** - * For how long will the helper allow signing? 0 if - * the key was revoked or purged. - */ - struct GNUNET_TIME_Relative validity_duration; - - /** - * Hash of the full donation unit key. - */ - struct DONAU_DonationUnitHashP h_donation_unit_pub; - - /** - * The (full) public key. - */ - struct DONAU_DonationUnitPublicKey donation_unit_pub; - - /** - * Signature over this key from the security module's key. - */ - struct TALER_SecurityModuleSignatureP sm_sig; - - /** - * Details depend on the @e donation_unit_pub.cipher type. - */ - union - { - - /** - * Hash of the RSA key. - */ - struct TALER_RsaPubHashP h_rsa; - - /** - * Hash of the CS key. - */ - struct TALER_CsPubHashP h_cs; - - } h_details; - - /** - * Name in configuration section for this donation unit type. - */ - char *section_name; - -}; - - -/** - * Information about a signing key on offer by the esign helper. - */ -// KILL! -struct HelperSignkey -{ - /** - * When will the helper start to use this key for signing? - */ - struct GNUNET_TIME_Timestamp start_time; - - /** - * For how long will the helper allow signing? 0 if - * the key was revoked or purged. - */ - struct GNUNET_TIME_Relative validity_duration; - - /** - * The public key. - */ - struct DONAU_DonauPublicKeyP donau_pub; - - /** - * Signature over this key from the security module's key. - */ - struct TALER_SecurityModuleSignatureP sm_sig; - -}; - /** * Counter incremented whenever we have a reason to re-build the keys because * something external changed. See #DH_keys_get_state() and @@ -340,22 +252,22 @@ struct HelperState struct TALER_CRYPTO_CsDenominationHelper *csdh; /** - * Map from H(donation_unit_pub) to `struct HelperDonationUnit` entries. + * Map from H(donation_unit_pub) to `struct DH_DonationUnitKey` entries. */ struct GNUNET_CONTAINER_MultiHashMap *donation_unit; /** - * Map from H(rsa_pub) to `struct HelperDonationUnit` entries. + * Map from H(rsa_pub) to `struct DH_DonationUnitKey` entries. */ struct GNUNET_CONTAINER_MultiHashMap *rsa_keys; /** - * Map from H(cs_pub) to `struct HelperDonationUnit` entries. + * Map from H(cs_pub) to `struct DH_DonationUnitKey` entries. */ struct GNUNET_CONTAINER_MultiHashMap *cs_keys; /** - * Map from `struct TALER_ExchangePublicKey` to `struct HelperSignkey` + * Map from `struct TALER_ExchangePublicKey` to `struct SigningKey` * entries. Based on the fact that a `struct GNUNET_PeerIdentity` is also * an EdDSA public key. */ @@ -364,17 +276,6 @@ struct HelperState }; /** - * Closure for #add_sign_key_cb. - */ -struct SignKeyCtx -{ - /** - * JSON array of signing keys (being created). - */ - json_t *signkeys; -}; - -/** * Function called to forcefully resume suspended keys requests. * * @param cls unused, NULL @@ -490,7 +391,7 @@ add_sign_key_cb (void *cls, const struct GNUNET_PeerIdentity *pid, void *value) { - struct SignKeyCtx *ctx = cls; + struct KeysBuilderContext *ctx = cls; struct SigningKey *sk = value; (void) pid; @@ -552,7 +453,7 @@ setup_general_response_headers (void *cls, * * @param cls the `struct FutureBuilderContext *` * @param h_du_pub hash of the donation unit public key - * @param value a `struct HelperDonationUnit` + * @param value a `struct DH_DonationUnitKey` * @return #GNUNET_OK (continue to iterate) */ static enum GNUNET_GenericReturnValue @@ -563,14 +464,14 @@ insert_donation_unit_cb (void *cls, struct KeysBuilderContext *kbc = cls; struct DH_DonationUnitKey *du = value; - if (GNUNET_TIME_relative_is_zero (hd->validity_duration)) - return GNUNET_OK; /* this key already expired! */ + // if (GNUNET_TIME_relative_is_zero (hd->validity_duration)) + // return GNUNET_OK; /* this key already expired! */ GNUNET_assert ( 0 == json_array_append_new ( kbc->donation_units, GNUNET_JSON_PACK ( - // GNUNET_JSON_pack_data_auto ("donation_unit_pub", - // &hd->donation_unit_pub), + DONAU_JSON_pack_donation_unit_pub ("donation_unit_pub", + &du->donation_unit_pub), GNUNET_JSON_pack_uint64 ("year", du->validity_year), TALER_JSON_pack_amount ("value", @@ -750,19 +651,18 @@ static enum GNUNET_GenericReturnValue finish_keys_response (struct DH_KeyStateHandle *ksh) { enum GNUNET_GenericReturnValue ret = GNUNET_SYSERR; - struct SignKeyCtx sctx; json_t *grouped_donation_units = NULL; struct GNUNET_HashContext *hash_context = NULL; struct KeysBuilderContext kbc; - sctx.signkeys = json_array (); - GNUNET_assert (NULL != sctx.signkeys); + kbc.signkeys = json_array (); + GNUNET_assert (NULL != kbc.signkeys); GNUNET_CONTAINER_multipeermap_iterate (ksh->signkey_map, &add_sign_key_cb, - &sctx); + &kbc); - if (0 == json_array_size (sctx.signkeys)) + if (0 == json_array_size (kbc.signkeys)) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "No online signing keys available. Refusing to generate /keys response.\n"); @@ -790,7 +690,7 @@ finish_keys_response (struct DH_KeyStateHandle *ksh) // if (GNUNET_OK != // create_keys_response (ksh, // &hc, - // sctx.signkeys, + // kbc.signkeys, // grouped_donation_units)) // { // GNUNET_log (GNUNET_ERROR_TYPE_WARNING, @@ -806,7 +706,7 @@ finish_keys_response (struct DH_KeyStateHandle *ksh) if (GNUNET_OK != create_keys_response (ksh, &hc, - sctx.signkeys, + kbc.signkeys, kbc.donation_units)) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, @@ -818,8 +718,8 @@ finish_keys_response (struct DH_KeyStateHandle *ksh) CLEANUP: // json_decref (grouped_donation_units); - if (NULL != sctx.signkeys) - json_decref (sctx.signkeys); + if (NULL != kbc.signkeys) + json_decref (kbc.signkeys); return ret; } @@ -997,9 +897,9 @@ check_esign_sm_pub (const struct TALER_SecurityModulePublicKeyP *sm_pub) * Helper function for #destroy_key_helpers to free all entries * in the `donation_unit` map. * - * @param cls the `struct HelperDonationUnit` + * @param cls the `struct DH_DonationUnitKey` * @param h_donation_unit_pub hash of the donation unit public key - * @param value the `struct HelperDonationUnit` to release + * @param value the `struct DH_DonationUnitKey` to release * @return #GNUNET_OK (continue to iterate) */ static enum GNUNET_GenericReturnValue @@ -1007,12 +907,11 @@ free_donation_unit_cb (void *cls, const struct GNUNET_HashCode *h_du_pub, void *value) { - struct HelperDonationUnit *hd = value; + struct DH_DonationUnitKey *hd = value; (void) cls; (void) h_du_pub; DONAU_donation_unit_pub_free (&hd->donation_unit_pub); - GNUNET_free (hd->section_name); GNUNET_free (hd); return GNUNET_OK; } @@ -1022,9 +921,9 @@ free_donation_unit_cb (void *cls, * Helper function for #destroy_key_helpers to free all entries * in the `esign_keys` map. * - * @param cls the `struct HelperSignkey` + * @param cls the `struct SigningKey` * @param pid unused, matches the donau public key - * @param value the `struct HelperSignkey` to release + * @param value the `struct SigningKey` to release * @return #GNUNET_OK (continue to iterate) */ static enum GNUNET_GenericReturnValue @@ -1032,7 +931,7 @@ free_esign_cb (void *cls, const struct GNUNET_PeerIdentity *pid, void *value) { - struct HelperSignkey *hsk = value; + struct SigningKey *hsk = value; (void) cls; (void) pid; @@ -1146,7 +1045,7 @@ helper_rsa_cb ( const struct TALER_SecurityModuleSignatureP *sm_sig) { struct HelperState *hs = cls; - struct HelperDonationUnit *hd; + struct DH_DonationUnitKey *hd; struct TALER_Amount value; enum GNUNET_DB_QueryStatus qs; @@ -1171,19 +1070,19 @@ helper_rsa_cb ( false)); hd = GNUNET_CONTAINER_multihashmap_get (hs->rsa_keys, &h_rsa->hash); - if (NULL != hd) - { - /* should be just an update (revocation!), so update existing entry */ - hd->validity_duration = validity_duration; - return; - } + // if (NULL != hd) + // { + // /* should be just an update (revocation!), so update existing entry */ + // hd->validity_duration = validity_duration; + // return; + // } GNUNET_assert (NULL != sm_pub); check_donation_unit_rsa_sm_pub (sm_pub); - hd = GNUNET_new (struct HelperDonationUnit); - hd->start_time = start_time; - hd->validity_duration = validity_duration; - hd->h_details.h_rsa = *h_rsa; - hd->sm_sig = *sm_sig; + hd = GNUNET_new (struct DH_DonationUnitKey); + // hd->start_time = start_time; + // hd->validity_duration = validity_duration; + // hd->h_details.h_rsa = *h_rsa; + // hd->sm_sig = *sm_sig; GNUNET_assert (GNUNET_CRYPTO_BSA_RSA == bs_pub->cipher); hd->donation_unit_pub.bsign_pub_key = GNUNET_CRYPTO_bsign_pub_incref (bs_pub); @@ -1203,7 +1102,7 @@ helper_rsa_cb ( GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Inserted donation unit of %s\n", TALER_amount2s (&value)); - hd->section_name = GNUNET_strdup (section_name); + GNUNET_assert ( GNUNET_OK == GNUNET_CONTAINER_multihashmap_put ( @@ -1211,13 +1110,13 @@ helper_rsa_cb ( &hd->h_donation_unit_pub.hash, hd, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); - GNUNET_assert ( - GNUNET_OK == - GNUNET_CONTAINER_multihashmap_put ( - hs->rsa_keys, - &hd->h_details.h_rsa.hash, - hd, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); + // GNUNET_assert ( + // GNUNET_OK == + // GNUNET_CONTAINER_multihashmap_put ( + // hs->rsa_keys, + // &hd->h_details.h_rsa.hash, + // hd, + // GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); key_generation++; DH_resume_keys_requests (false); } @@ -1250,7 +1149,7 @@ helper_cs_cb ( const struct TALER_SecurityModuleSignatureP *sm_sig) { struct HelperState *hs = cls; - struct HelperDonationUnit *hd; + struct DH_DonationUnitKey *hd; struct TALER_Amount value; enum GNUNET_DB_QueryStatus qs; @@ -1277,18 +1176,18 @@ helper_cs_cb ( hd = GNUNET_CONTAINER_multihashmap_get (hs->cs_keys, &h_cs->hash); - if (NULL != hd) - { - /* should be just an update (revocation!), so update existing entry */ - hd->validity_duration = validity_duration; - return; - } + // if (NULL != hd) + // { + // /* should be just an update (revocation!), so update existing entry */ + // hd->validity_duration = validity_duration; + // return; + // } GNUNET_assert (NULL != sm_pub); check_donation_unit_cs_sm_pub (sm_pub); - hd = GNUNET_new (struct HelperDonationUnit); - hd->start_time = start_time; - hd->validity_duration = validity_duration; - hd->h_details.h_cs = *h_cs; + hd = GNUNET_new (struct DH_DonationUnitKey); + // hd->start_time = start_time; + // hd->validity_duration = validity_duration; + // hd->h_details.h_cs = *h_cs; GNUNET_assert (GNUNET_CRYPTO_BSA_CS == bs_pub->cipher); hd->donation_unit_pub.bsign_pub_key = GNUNET_CRYPTO_bsign_pub_incref (bs_pub); @@ -1308,7 +1207,7 @@ helper_cs_cb ( GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Inserted donation unit of %s\n", TALER_amount2s (&value)); - hd->section_name = GNUNET_strdup (section_name); + GNUNET_assert ( GNUNET_OK == GNUNET_CONTAINER_multihashmap_put ( @@ -1316,13 +1215,13 @@ helper_cs_cb ( &hd->h_donation_unit_pub.hash, hd, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); - GNUNET_assert ( - GNUNET_OK == - GNUNET_CONTAINER_multihashmap_put ( - hs->cs_keys, - &hd->h_details.h_cs.hash, - hd, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); + // GNUNET_assert ( + // GNUNET_OK == + // GNUNET_CONTAINER_multihashmap_put ( + // hs->cs_keys, + // &hd->h_details.h_cs.hash, + // hd, + // GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); key_generation++; DH_resume_keys_requests (false); } @@ -1353,7 +1252,7 @@ helper_esign_cb ( const struct TALER_SecurityModuleSignatureP *sm_sig) { struct HelperState *hs = cls; - struct HelperSignkey *hsk; + struct SigningKey *hsk; struct GNUNET_PeerIdentity pid; /* need to "cast" because secmod works with TALER_ExchangePublicKeyP */ struct DONAU_DonauPublicKeyP donau_pubkey = { @@ -1370,18 +1269,18 @@ helper_esign_cb ( pid.public_key = donau_pub->eddsa_pub; hsk = GNUNET_CONTAINER_multipeermap_get (hs->esign_keys, &pid); - if (NULL != hsk) - { - GNUNET_break (0); // revocation not supported - /* should be just an update (revocation!), so update existing entry */ - // hsk->validity_duration = validity_duration; - return; - } + // if (NULL != hsk) + // { + // GNUNET_break (0); // revocation not supported + // /* should be just an update (revocation!), so update existing entry */ + // // hsk->validity_duration = validity_duration; + // return; + // } GNUNET_assert (NULL != sm_pub); check_esign_sm_pub (sm_pub); - hsk = GNUNET_new (struct HelperSignkey); - hsk->start_time = start_time; - hsk->validity_duration = validity_duration; + hsk = GNUNET_new (struct SigningKey); + // hsk->start_time = start_time; + // hsk->validity_duration = validity_duration; hsk->donau_pub = donau_pubkey; { struct DONAUDB_SignkeyMetaData meta = { @@ -1712,7 +1611,7 @@ DH_keys_get_state () * * @param cls the `struct FutureBuilderContext *` * @param pid actually the donau public key (type disguised) - * @param value a `struct HelperDonationUnit` + * @param value a `struct DH_DonationUnitKey` * @return #GNUNET_OK (continue to iterate) */ static enum GNUNET_GenericReturnValue @@ -1721,7 +1620,7 @@ add_signkey_cb (void *cls, void *value) { struct KeysBuilderContext *kbc = cls; - struct HelperSignkey *hsk = value; + struct SigningKey *hsk = value; struct SigningKey *sk; struct GNUNET_TIME_Timestamp stamp_expire; @@ -1734,9 +1633,9 @@ add_signkey_cb (void *cls, // if (GNUNET_TIME_relative_is_zero (hsk->validity_duration)) // return GNUNET_OK; /* this key already expired! */ - stamp_expire = GNUNET_TIME_absolute_to_timestamp ( - GNUNET_TIME_absolute_add (hsk->start_time.abs_time, - hsk->validity_duration)); + // stamp_expire = GNUNET_TIME_absolute_to_timestamp ( + // GNUNET_TIME_absolute_add (hsk->start_time.abs_time, + // hsk->validity_duration)); // legal_end = GNUNET_TIME_absolute_to_timestamp ( // GNUNET_TIME_absolute_add (stamp_expire.abs_time, @@ -1747,15 +1646,16 @@ add_signkey_cb (void *cls, kbc->signkeys, GNUNET_JSON_PACK ( GNUNET_JSON_pack_data_auto ("key", - &hsk->donau_pub), - GNUNET_JSON_pack_timestamp ("stamp_start", - hsk->start_time), - GNUNET_JSON_pack_timestamp ("stamp_expire", - stamp_expire), + &hsk->donau_pub) // , + // GNUNET_JSON_pack_timestamp ("stamp_start", + // hsk->start_time), + // GNUNET_JSON_pack_timestamp ("stamp_expire", + // stamp_expire), // GNUNET_JSON_pack_timestamp ("stamp_end", // legal_end), - GNUNET_JSON_pack_data_auto ("signkey_secmod_sig", - &hsk->sm_sig)))); + // GNUNET_JSON_pack_data_auto ("signkey_secmod_sig", + // &hsk->sm_sig) + ))); return GNUNET_OK; } diff --git a/src/include/Makefile.am b/src/include/Makefile.am @@ -1,7 +1,7 @@ # This Makefile.am is in the public domain -talerincludedir = $(includedir)/taler +donauincludedir = $(includedir)/donau -talerinclude_HEADERS = \ +donauinclude_HEADERS = \ donau_service.h \ donau_signatures.h \ donaudb_lib.h \ diff --git a/src/include/donau_json_lib.h b/src/include/donau_json_lib.h @@ -71,4 +71,17 @@ struct GNUNET_JSON_PackSpec DONAU_JSON_pack_uint32 (const char *name, uint64_t num); +/** + * Generate packer instruction for a JSON field of type + * denomination public key. + * + * @param name name of the field to add to the object + * @param pk public key + * @return json pack specification + */ +struct GNUNET_JSON_PackSpec +DONAU_JSON_pack_donation_unit_pub ( + const char *name, + const struct DONAU_DonationUnitPublicKey *pk); + #endif diff --git a/src/json/json_helper.c b/src/json/json_helper.c @@ -26,624 +26,4 @@ #include <taler/taler_json_lib.h> -/** - * Convert string value to numeric cipher value. - * - * @param cipher_s input string - * @return numeric cipher value - */ -static enum GNUNET_CRYPTO_BlindSignatureAlgorithm -string_to_cipher (const char *cipher_s) -{ - if ((0 == strcasecmp (cipher_s, - "RSA"))) - return GNUNET_CRYPTO_BSA_RSA; - if ((0 == strcasecmp (cipher_s, - "CS"))) - return GNUNET_CRYPTO_BSA_CS; - return GNUNET_CRYPTO_BSA_INVALID; -} - - -json_t * -TALER_JSON_from_amount (const struct TALER_Amount *amount) -{ - char *amount_str = TALER_amount_to_string (amount); - - GNUNET_assert (NULL != amount_str); - { - json_t *j = json_string (amount_str); - - GNUNET_free (amount_str); - return j; - } -} - - -/** - * Parse given JSON object to Amount - * - * @param cls closure, expected currency, or NULL - * @param root the json object representing data - * @param[out] spec where to write the data - * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error - */ -static enum GNUNET_GenericReturnValue -parse_amount (void *cls, - json_t *root, - struct GNUNET_JSON_Specification *spec) -{ - const char *currency = cls; - struct TALER_Amount *r_amount = spec->ptr; - - (void) cls; - if (! json_is_string (root)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - if (GNUNET_OK != - TALER_string_to_amount (json_string_value (root), - r_amount)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - if ( (NULL != currency) && - (0 != - strcasecmp (currency, - r_amount->currency)) ) - { - GNUNET_break_op (0); - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Expected currency `%s', but amount used currency `%s' in field `%s'\n", - currency, - r_amount->currency, - spec->field); - return GNUNET_SYSERR; - } - return GNUNET_OK; -} - - -struct GNUNET_JSON_Specification -TALER_JSON_spec_amount (const char *name, - const char *currency, - struct TALER_Amount *r_amount) -{ - struct GNUNET_JSON_Specification ret = { - .parser = &parse_amount, - .cleaner = NULL, - .cls = (void *) currency, - .field = name, - .ptr = r_amount, - .ptr_size = 0, - .size_ptr = NULL - }; - - GNUNET_assert (NULL != currency); - return ret; -} - - -struct GNUNET_JSON_Specification -TALER_JSON_spec_amount_any (const char *name, - struct TALER_Amount *r_amount) -{ - struct GNUNET_JSON_Specification ret = { - .parser = &parse_amount, - .cleaner = NULL, - .cls = NULL, - .field = name, - .ptr = r_amount, - .ptr_size = 0, - .size_ptr = NULL - }; - - return ret; -} - - -/** - * Parse given JSON object to currency spec. - * - * @param cls closure, NULL - * @param root the json object representing data - * @param[out] spec where to write the data - * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error - */ -static enum GNUNET_GenericReturnValue -parse_cspec (void *cls, - json_t *root, - struct GNUNET_JSON_Specification *spec) -{ - struct TALER_CurrencySpecification *r_cspec = spec->ptr; - const char *currency = spec->cls; - const char *name; - uint32_t fid; - uint32_t fnd; - uint32_t ftzd; - const json_t *map; - struct GNUNET_JSON_Specification gspec[] = { - GNUNET_JSON_spec_string ("name", - &name), - GNUNET_JSON_spec_uint32 ("num_fractional_input_digits", - &fid), - GNUNET_JSON_spec_uint32 ("num_fractional_normal_digits", - &fnd), - GNUNET_JSON_spec_uint32 ("num_fractional_trailing_zero_digits", - &ftzd), - GNUNET_JSON_spec_object_const ("alt_unit_names", - &map), - GNUNET_JSON_spec_end () - }; - const char *emsg; - unsigned int eline; - - memset (r_cspec->currency, - 0, - sizeof (r_cspec->currency)); - if (GNUNET_OK != - GNUNET_JSON_parse (root, - gspec, - &emsg, - &eline)) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Failed to parse %s at %u: %s\n", - spec[eline].field, - eline, - emsg); - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - if (strlen (currency) >= TALER_CURRENCY_LEN) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - if ( (fid > TALER_AMOUNT_FRAC_LEN) || - (fnd > TALER_AMOUNT_FRAC_LEN) || - (ftzd > TALER_AMOUNT_FRAC_LEN) ) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - if (GNUNET_OK != - TALER_check_currency (currency)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - strcpy (r_cspec->currency, - currency); - if (GNUNET_OK != - TALER_check_currency_scale_map (map)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - r_cspec->name = GNUNET_strdup (name); - r_cspec->map_alt_unit_names = json_incref ((json_t *) map); - return GNUNET_OK; -} - - -/** - * Cleanup data left from parsing encrypted contract. - * - * @param cls closure, NULL - * @param[out] spec where to free the data - */ -static void -clean_cspec (void *cls, - struct GNUNET_JSON_Specification *spec) -{ - struct TALER_CurrencySpecification *cspec = spec->ptr; - - (void) cls; - GNUNET_free (cspec->name); - json_decref (cspec->map_alt_unit_names); -} - - -struct GNUNET_JSON_Specification -TALER_JSON_spec_currency_specification ( - const char *name, - const char *currency, - struct TALER_CurrencySpecification *r_cspec) -{ - struct GNUNET_JSON_Specification ret = { - .parser = &parse_cspec, - .cleaner = &clean_cspec, - .cls = (void *) currency, - .field = name, - .ptr = r_cspec, - .ptr_size = sizeof (*r_cspec), - .size_ptr = NULL - }; - - memset (r_cspec, - 0, - sizeof (*r_cspec)); - return ret; -} - - -/** - * Parse given JSON object to an encrypted contract. - * - * @param cls closure, NULL - * @param root the json object representing data - * @param[out] spec where to write the data - * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error - */ -static enum GNUNET_GenericReturnValue -parse_econtract (void *cls, - json_t *root, - struct GNUNET_JSON_Specification *spec) -{ - struct TALER_EncryptedContract *econtract = spec->ptr; - struct GNUNET_JSON_Specification ispec[] = { - GNUNET_JSON_spec_varsize ("econtract", - &econtract->econtract, - &econtract->econtract_size), - GNUNET_JSON_spec_fixed_auto ("econtract_sig", - &econtract->econtract_sig), - GNUNET_JSON_spec_fixed_auto ("contract_pub", - &econtract->contract_pub), - GNUNET_JSON_spec_end () - }; - const char *emsg; - unsigned int eline; - - (void) cls; - if (GNUNET_OK != - GNUNET_JSON_parse (root, - ispec, - &emsg, - &eline)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - return GNUNET_OK; -} - - -/** - * Cleanup data left from parsing encrypted contract. - * - * @param cls closure, NULL - * @param[out] spec where to free the data - */ -static void -clean_econtract (void *cls, - struct GNUNET_JSON_Specification *spec) -{ - struct TALER_EncryptedContract *econtract = spec->ptr; - - (void) cls; - GNUNET_free (econtract->econtract); -} - - -struct GNUNET_JSON_Specification -TALER_JSON_spec_econtract (const char *name, - struct TALER_EncryptedContract *econtract) -{ - struct GNUNET_JSON_Specification ret = { - .parser = &parse_econtract, - .cleaner = &clean_econtract, - .field = name, - .ptr = econtract - }; - - return ret; -} - - -/** - * Closure for #parse_i18n_string. - */ -struct I18nContext -{ - /** - * Language pattern to match. - */ - char *lp; - - /** - * Name of the field to match. - */ - const char *field; -}; - - -/** - * Parse given JSON object to internationalized string. - * - * @param cls closure, our `struct I18nContext *` - * @param root the json object representing data - * @param[out] spec where to write the data - * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error - */ -static enum GNUNET_GenericReturnValue -parse_i18n_string (void *cls, - json_t *root, - struct GNUNET_JSON_Specification *spec) -{ - struct I18nContext *ctx = cls; - json_t *i18n; - json_t *val; - - { - char *i18nf; - - GNUNET_asprintf (&i18nf, - "%s_i18n", - ctx->field); - i18n = json_object_get (root, - i18nf); - GNUNET_free (i18nf); - } - - val = json_object_get (root, - ctx->field); - if ( (NULL != i18n) && - (NULL != ctx->lp) ) - { - double best = 0.0; - json_t *pos; - const char *lang; - - json_object_foreach (i18n, lang, pos) - { - double score; - - score = TALER_language_matches (ctx->lp, - lang); - if (score > best) - { - best = score; - val = pos; - } - } - } - - { - const char *str; - - str = json_string_value (val); - *(const char **) spec->ptr = str; - } - return GNUNET_OK; -} - - -/** - * Function called to clean up data from earlier parsing. - * - * @param cls closure - * @param spec our specification entry with data to clean. - */ -static void -i18n_cleaner (void *cls, - struct GNUNET_JSON_Specification *spec) -{ - struct I18nContext *ctx = cls; - - (void) spec; - if (NULL != ctx) - { - GNUNET_free (ctx->lp); - GNUNET_free (ctx); - } -} - - -struct GNUNET_JSON_Specification -TALER_JSON_spec_i18n_string (const char *name, - const char *language_pattern, - const char **strptr) -{ - struct I18nContext *ctx = GNUNET_new (struct I18nContext); - struct GNUNET_JSON_Specification ret = { - .parser = &parse_i18n_string, - .cleaner = &i18n_cleaner, - .cls = ctx, - .field = NULL, /* we want the main object */ - .ptr = strptr, - .ptr_size = 0, - .size_ptr = NULL - }; - - ctx->lp = (NULL != language_pattern) - ? GNUNET_strdup (language_pattern) - : NULL; - ctx->field = name; - *strptr = NULL; - return ret; -} - - -struct GNUNET_JSON_Specification -TALER_JSON_spec_i18n_str (const char *name, - const char **strptr) -{ - const char *lang = getenv ("LANG"); - char *dot; - char *l; - struct GNUNET_JSON_Specification ret; - - if (NULL != lang) - { - dot = strchr (lang, - '.'); - if (NULL == dot) - l = GNUNET_strdup (lang); - else - l = GNUNET_strndup (lang, - dot - lang); - } - else - { - l = NULL; - } - ret = TALER_JSON_spec_i18n_string (name, - l, - strptr); - GNUNET_free (l); - return ret; -} - - -/** - * Parse given JSON object with Taler error code. - * - * @param cls closure, NULL - * @param root the json object representing data - * @param[out] spec where to write the data - * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error - */ -static enum GNUNET_GenericReturnValue -parse_ec (void *cls, - json_t *root, - struct GNUNET_JSON_Specification *spec) -{ - enum TALER_ErrorCode *ec = spec->ptr; - json_int_t num; - - (void) cls; - if (! json_is_integer (root)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - num = json_integer_value (root); - if (num < 0) - { - GNUNET_break_op (0); - *ec = TALER_EC_INVALID; - return GNUNET_SYSERR; - } - *ec = (enum TALER_ErrorCode) num; - return GNUNET_OK; -} - - -struct GNUNET_JSON_Specification -TALER_JSON_spec_ec (const char *field, - enum TALER_ErrorCode *ec) -{ - struct GNUNET_JSON_Specification ret = { - .parser = &parse_ec, - .field = field, - .ptr = ec - }; - - *ec = TALER_EC_NONE; - return ret; -} - - -/** - * Parse given JSON object to web URL. - * - * @param cls closure, NULL - * @param root the json object representing data - * @param[out] spec where to write the data - * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error - */ -static enum GNUNET_GenericReturnValue -parse_web_url (void *cls, - json_t *root, - struct GNUNET_JSON_Specification *spec) -{ - const char *str; - - (void) cls; - str = json_string_value (root); - if (NULL == str) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - if (! TALER_is_web_url (str)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - *(const char **) spec->ptr = str; - return GNUNET_OK; -} - - -struct GNUNET_JSON_Specification -TALER_JSON_spec_web_url (const char *field, - const char **url) -{ - struct GNUNET_JSON_Specification ret = { - .parser = &parse_web_url, - .field = field, - .ptr = url - }; - - *url = NULL; - return ret; -} - - -/** - * Parse given JSON object with protocol version. - * - * @param cls closure, NULL - * @param root the json object representing data - * @param[out] spec where to write the data - * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error - */ -static enum GNUNET_GenericReturnValue -parse_protocol_version (void *cls, - json_t *root, - struct GNUNET_JSON_Specification *spec) -{ - struct TALER_JSON_ProtocolVersion *pv = spec->ptr; - const char *ver; - char dummy; - - (void) cls; - if (! json_is_string (root)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - ver = json_string_value (root); - if (3 != sscanf (ver, - "%u:%u:%u%c", - &pv->current, - &pv->revision, - &pv->age, - &dummy)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - return GNUNET_OK; -} - - -struct GNUNET_JSON_Specification -TALER_JSON_spec_version (const char *field, - struct TALER_JSON_ProtocolVersion *ver) -{ - struct GNUNET_JSON_Specification ret = { - .parser = &parse_protocol_version, - .field = field, - .ptr = ver - }; - - return ret; -} - - /* end of json/json_helper.c */ diff --git a/src/json/json_pack.c b/src/json/json_pack.c @@ -22,84 +22,12 @@ #include <gnunet/gnunet_util_lib.h> #include <taler/taler_util.h> #include <taler/taler_json_lib.h> - - -struct GNUNET_JSON_PackSpec -TALER_JSON_pack_time_abs_human (const char *name, - struct GNUNET_TIME_Absolute at) -{ - struct GNUNET_JSON_PackSpec ps = { - .field_name = name, - .object = json_string ( - GNUNET_STRINGS_absolute_time_to_string (at)) - }; - - return ps; -} - - -struct GNUNET_JSON_PackSpec -TALER_JSON_pack_econtract ( - const char *name, - const struct TALER_EncryptedContract *econtract) -{ - struct GNUNET_JSON_PackSpec ps = { - .field_name = name, - }; - - if (NULL == econtract) - return ps; - ps.object - = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_data_varsize ("econtract", - econtract->econtract, - econtract->econtract_size), - GNUNET_JSON_pack_data_auto ("econtract_sig", - &econtract->econtract_sig), - GNUNET_JSON_pack_data_auto ("contract_pub", - &econtract->contract_pub)); - return ps; -} - +#include <donau_util.h> struct GNUNET_JSON_PackSpec -TALER_JSON_pack_age_commitment ( +DONAU_JSON_pack_donation_unit_pub ( const char *name, - const struct TALER_AgeCommitment *age_commitment) -{ - struct GNUNET_JSON_PackSpec ps = { - .field_name = name, - }; - json_t *keys; - - if (NULL == age_commitment || - 0 == age_commitment->num) - return ps; - - GNUNET_assert (NULL != - (keys = json_array ())); - - for (size_t i = 0; - i < age_commitment->num; - i++) - { - json_t *val; - val = GNUNET_JSON_from_data (&age_commitment->keys[i], - sizeof(age_commitment->keys[i])); - GNUNET_assert (NULL != val); - GNUNET_assert (0 == - json_array_append_new (keys, val)); - } - - ps.object = keys; - return ps; -} - - -struct GNUNET_JSON_PackSpec -TALER_JSON_pack_denom_pub ( - const char *name, - const struct TALER_DenominationPublicKey *pk) + const struct DONAU_DonationUnitPublicKey *pk) { const struct GNUNET_CRYPTO_BlindSignPublicKey *bsp; struct GNUNET_JSON_PackSpec ps = { @@ -118,8 +46,6 @@ TALER_JSON_pack_denom_pub ( = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("cipher", "RSA"), - GNUNET_JSON_pack_uint64 ("age_mask", - pk->age_mask.bits), GNUNET_JSON_pack_rsa_public_key ("rsa_public_key", bsp->details.rsa_public_key)); return ps; @@ -128,8 +54,6 @@ TALER_JSON_pack_denom_pub ( = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("cipher", "CS"), - GNUNET_JSON_pack_uint64 ("age_mask", - pk->age_mask.bits), GNUNET_JSON_pack_data_varsize ("cs_public_key", &bsp->details.cs_public_key, sizeof (bsp->details.cs_public_key))); @@ -140,185 +64,4 @@ TALER_JSON_pack_denom_pub ( } -struct GNUNET_JSON_PackSpec -TALER_JSON_pack_denom_sig ( - const char *name, - const struct TALER_DenominationSignature *sig) -{ - const struct GNUNET_CRYPTO_UnblindedSignature *bs; - struct GNUNET_JSON_PackSpec ps = { - .field_name = name, - }; - - if (NULL == sig) - return ps; - bs = sig->unblinded_sig; - switch (bs->cipher) - { - case GNUNET_CRYPTO_BSA_INVALID: - break; - case GNUNET_CRYPTO_BSA_RSA: - ps.object = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("cipher", - "RSA"), - GNUNET_JSON_pack_rsa_signature ("rsa_signature", - bs->details.rsa_signature)); - return ps; - case GNUNET_CRYPTO_BSA_CS: - ps.object = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("cipher", - "CS"), - GNUNET_JSON_pack_data_auto ("cs_signature_r", - &bs->details.cs_signature.r_point), - GNUNET_JSON_pack_data_auto ("cs_signature_s", - &bs->details.cs_signature.s_scalar)); - return ps; - } - GNUNET_assert (0); - return ps; -} - - -struct GNUNET_JSON_PackSpec -TALER_JSON_pack_exchange_withdraw_values ( - const char *name, - const struct TALER_ExchangeWithdrawValues *ewv) -{ - const struct GNUNET_CRYPTO_BlindingInputValues *biv; - struct GNUNET_JSON_PackSpec ps = { - .field_name = name, - }; - - if (NULL == ewv) - return ps; - biv = ewv->blinding_inputs; - switch (biv->cipher) - { - case GNUNET_CRYPTO_BSA_INVALID: - break; - case GNUNET_CRYPTO_BSA_RSA: - ps.object = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("cipher", - "RSA")); - return ps; - case GNUNET_CRYPTO_BSA_CS: - ps.object = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("cipher", - "CS"), - GNUNET_JSON_pack_data_varsize ( - "r_pub_0", - &biv->details.cs_values.r_pub[0], - sizeof(struct GNUNET_CRYPTO_CsRPublic)), - GNUNET_JSON_pack_data_varsize ( - "r_pub_1", - &biv->details.cs_values.r_pub[1], - sizeof(struct GNUNET_CRYPTO_CsRPublic)) - ); - return ps; - } - GNUNET_assert (0); - return ps; -} - - -struct GNUNET_JSON_PackSpec -TALER_JSON_pack_blinded_denom_sig ( - const char *name, - const struct TALER_BlindedDenominationSignature *sig) -{ - const struct GNUNET_CRYPTO_BlindedSignature *bs; - struct GNUNET_JSON_PackSpec ps = { - .field_name = name, - }; - - if (NULL == sig) - return ps; - bs = sig->blinded_sig; - switch (bs->cipher) - { - case GNUNET_CRYPTO_BSA_INVALID: - break; - case GNUNET_CRYPTO_BSA_RSA: - ps.object = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("cipher", - "RSA"), - GNUNET_JSON_pack_rsa_signature ("blinded_rsa_signature", - bs->details.blinded_rsa_signature)); - return ps; - case GNUNET_CRYPTO_BSA_CS: - ps.object = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("cipher", - "CS"), - GNUNET_JSON_pack_uint64 ("b", - bs->details.blinded_cs_answer.b), - GNUNET_JSON_pack_data_auto ("s", - &bs->details.blinded_cs_answer.s_scalar)); - return ps; - } - GNUNET_assert (0); - return ps; -} - - -struct GNUNET_JSON_PackSpec -TALER_JSON_pack_blinded_planchet ( - const char *name, - const struct TALER_BlindedPlanchet *blinded_planchet) -{ - const struct GNUNET_CRYPTO_BlindedMessage *bm; - struct GNUNET_JSON_PackSpec ps = { - .field_name = name, - }; - - if (NULL == blinded_planchet) - return ps; - bm = blinded_planchet->blinded_message; - switch (bm->cipher) - { - case GNUNET_CRYPTO_BSA_INVALID: - break; - case GNUNET_CRYPTO_BSA_RSA: - ps.object = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("cipher", - "RSA"), - GNUNET_JSON_pack_data_varsize ( - "rsa_blinded_planchet", - bm->details.rsa_blinded_message.blinded_msg, - bm->details.rsa_blinded_message.blinded_msg_size)); - return ps; - case GNUNET_CRYPTO_BSA_CS: - ps.object = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("cipher", - "CS"), - GNUNET_JSON_pack_data_auto ( - "cs_nonce", - &bm->details.cs_blinded_message.nonce), - GNUNET_JSON_pack_data_auto ( - "cs_blinded_c0", - &bm->details.cs_blinded_message.c[0]), - GNUNET_JSON_pack_data_auto ( - "cs_blinded_c1", - &bm->details.cs_blinded_message.c[1])); - return ps; - } - GNUNET_assert (0); - return ps; -} - - -struct GNUNET_JSON_PackSpec -TALER_JSON_pack_amount (const char *name, - const struct TALER_Amount *amount) -{ - struct GNUNET_JSON_PackSpec ps = { - .field_name = name, - .object = (NULL != amount) - ? TALER_JSON_from_amount (amount) - : NULL - }; - - return ps; -} - - /* End of json/json_pack.c */