donau

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

commit ee6b9311792db3af424a9309391757367c013782
parent 2de49c1a5f66ba4a637bf59456ebd5fbb4ac02d3
Author: Matyja Lukas Adam <lukas.matyja@students.bfh.ch>
Date:   Tue, 28 Nov 2023 01:10:45 +0100

[lib] implement some methods

Diffstat:
Msrc/include/donau_crypto_lib.h | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/include/donau_service.h | 29-----------------------------
Msrc/lib/donau_api_handle.c | 395++++++++-----------------------------------------------------------------------
Asrc/util/donau_crypto.c | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 161 insertions(+), 387 deletions(-)

diff --git a/src/include/donau_crypto_lib.h b/src/include/donau_crypto_lib.h @@ -87,6 +87,29 @@ struct DONAU_CharityPrivateKeyP }; /** + * @brief Type of public signing keys for verifying blindly signed budis. + */ +struct DONAU_DonationUnitPublicKey +{ + + /** + * Type of the public key. + */ + struct GNUNET_CRYPTO_BlindSignPublicKey *bsign_pub_key; + +}; + +/** + * @brief Type of private signing keys for blind signing of budis. + */ +struct DONAU_DonationUnitPrivateKey +{ + + struct GNUNET_CRYPTO_BlindSignPrivateKey *bsign_priv_key; + +}; + +/** * Hash of a donation unit public key */ struct DONAU_DonationUnitHashP @@ -258,4 +281,43 @@ DONAU_donation_statement_verify ( const struct DONAU_DonauSignatureP *statement_sig); +/* ********************* helper ************************** */ + + +/** + * Group of donation units. These are the common fields of an array of + * donation units. + * + * The corresponding JSON-blob will also contain an array of particular + * denominations with only the cipher-specific public key and the + * corresponding year. + */ +struct DONAU_DonationUnitGroup +{ + + /** + * Value of coins in this donation unit group. + */ + struct TALER_Amount value; + + /** + * Cipher used for the donation unit. + */ + enum GNUNET_CRYPTO_BlindSignatureAlgorithm cipher; + +}; + +/** + * Compute a unique key for the meta data of a donation unit group. + * + * @param dg donation unit group to evaluate + * @param[out] key key to set + */ +void +TALER_donation_unit_group_get_key ( + const struct DONAU_DonationUnitGroup *dg, + struct GNUNET_HashCode *key); + + + #endif diff --git a/src/include/donau_service.h b/src/include/donau_service.h @@ -54,35 +54,6 @@ struct TALER_DONAU_SigningPublicKeyAndValidity /** - * @brief Type of public signing keys for verifying blindly signed donation receipts. - */ -struct TALER_DonationUnitPublicKey -{ - - /** - * Type of the public key (RSA or CS). - */ - enum GNUNET_CRYPTO_BlindSignatureAlgorithm cipher; - - /** - * Details, depending on @e cipher. - */ - union - { - /** - * If we use #TALER_DENOMINATION_CS in @a cipher. - */ - struct GNUNET_CRYPTO_CsPublicKey cs_public_key; - - /** - * If we use #TALER_DENOMINATION_RSA in @a cipher. - */ - struct GNUNET_CRYPTO_RsaPublicKey *rsa_public_key; - - } details; -}; - -/** * @brief Public information about a donau's donation unit signing key */ struct TALER_DonationUnitInformation diff --git a/src/lib/donau_api_handle.c b/src/lib/donau_api_handle.c @@ -284,20 +284,10 @@ decode_keys_json (const json_t *resp_obj, enum TALER_DONAU_VersionCompatibility *vc) { struct TALER_DonauSignatureP denominations_sig; - struct GNUNET_HashCode hash_xor = {0}; struct TALER_DonauPublicKeyP pub; - const json_t *wblwk = NULL; - const json_t *global_fees; const json_t *sign_keys_array; - const json_t *denominations_by_group; - const json_t *auditors_array; - const json_t *recoup_array = NULL; - const json_t *manifests = NULL; - bool no_extensions = false; + const json_t *donation_units_by_group; bool no_signature = false; - const json_t *accounts; - const json_t *fees; - const json_t *wads; if (JSON_OBJECT != json_typeof (resp_obj)) { @@ -1399,25 +1389,25 @@ TALER_DONAU_keys_from_json (const json_t *j) /** - * Data we track per denomination group. + * Data we track per donation unit group. */ struct GroupData { /** - * The json blob with the group meta-data and list of denominations + * The json blob with the group meta-data and list of donation units */ json_t *json; /** * Meta data for this group. */ - struct TALER_DenominationGroup meta; + struct DONAU_DonationUnitGroup meta; }; /** - * Add denomination group represented by @a value - * to list of denominations in @a cls. Also frees + * Add donation unit group represented by @a value + * to list of donation units in @a cls. Also frees * the @a value. * * @param[in,out] cls a `json_t *` with an array to build @@ -1430,19 +1420,18 @@ add_grp (void *cls, const struct GNUNET_HashCode *key, void *value) { - json_t *denominations_by_group = cls; + json_t *donation_units_by_group = cls; struct GroupData *gd = value; const char *cipher; json_t *ge; - bool age_restricted = gd->meta.age_mask.bits != 0; (void) key; switch (gd->meta.cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_RSA: cipher = age_restricted ? "RSA+age_restricted" : "RSA"; break; - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: cipher = age_restricted ? "CS+age_restricted" : "CS"; break; default: @@ -1456,153 +1445,66 @@ add_grp (void *cls, cipher), GNUNET_JSON_pack_array_steal ("denoms", gd->json), - TALER_JSON_PACK_DENOM_FEES ("fee", - &gd->meta.fees), - GNUNET_JSON_pack_allow_null ( - age_restricted - ? GNUNET_JSON_pack_uint64 ("age_mask", - gd->meta.age_mask.bits) - : GNUNET_JSON_pack_string ("dummy", - NULL)), TALER_JSON_pack_amount ("value", &gd->meta.value)); GNUNET_assert (0 == - json_array_append_new (denominations_by_group, + json_array_append_new (donation_units_by_group, ge)); GNUNET_free (gd); return GNUNET_OK; } -/** - * Convert array of account restrictions @a ars to JSON. - * - * @param ar_len length of @a ars - * @param ars account restrictions to convert - * @return JSON representation - */ -static json_t * -ar_to_json (unsigned int ar_len, - const struct TALER_DONAU_AccountRestriction ars[static ar_len]) -{ - json_t *rval; - - rval = json_array (); - GNUNET_assert (NULL != rval); - for (unsigned int i = 0; i<ar_len; i++) - { - const struct TALER_DONAU_AccountRestriction *ar = &ars[i]; - - switch (ar->type) - { - case TALER_DONAU_AR_INVALID: - GNUNET_break (0); - json_decref (rval); - return NULL; - case TALER_DONAU_AR_DENY: - GNUNET_assert ( - 0 == - json_array_append_new ( - rval, - GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("type", - "deny")))); - break; - case TALER_DONAU_AR_REGEX: - GNUNET_assert ( - 0 == - json_array_append_new ( - rval, - GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ( - "type", - "regex"), - GNUNET_JSON_pack_string ( - "regex", - ar->details.regex.posix_egrep), - GNUNET_JSON_pack_string ( - "human_hint", - ar->details.regex.human_hint), - GNUNET_JSON_pack_object_incref ( - "human_hint_i18n", - (json_t *) ar->details.regex.human_hint_i18n) - ))); - break; - } - } - return rval; -} - - json_t * TALER_DONAU_keys_to_json (const struct TALER_DONAU_Keys *kd) { - struct GNUNET_TIME_Timestamp now; json_t *keys; json_t *signkeys; - json_t *denominations_by_group; - json_t *auditors; - json_t *recoup; - json_t *wire_fees; + json_t *donation_units; json_t *accounts; - json_t *global_fees; - json_t *wblwk = NULL; now = GNUNET_TIME_timestamp_get (); signkeys = json_array (); GNUNET_assert (NULL != signkeys); for (unsigned int i = 0; i<kd->num_sign_keys; i++) { - const struct TALER_DONAU_SigningPublicKey *sk = &kd->sign_keys[i]; + const struct TALER_DONAU_SigningPublicKeyAndValidity *sk = &kd->sign_keys[i]; json_t *signkey; - if (GNUNET_TIME_timestamp_cmp (now, - >, - sk->valid_until)) - continue; /* skip keys that have expired */ signkey = GNUNET_JSON_PACK ( GNUNET_JSON_pack_data_auto ("key", &sk->key), - GNUNET_JSON_pack_data_auto ("master_sig", - &sk->master_sig), - GNUNET_JSON_pack_timestamp ("stamp_start", - sk->valid_from), - GNUNET_JSON_pack_timestamp ("stamp_expire", - sk->valid_until), - GNUNET_JSON_pack_timestamp ("stamp_end", - sk->valid_legal)); + GNUNET_JSON_pack_uint64 ("year", + &sk->year)); GNUNET_assert (NULL != signkey); GNUNET_assert (0 == json_array_append_new (signkeys, signkey)); } - denominations_by_group = json_array (); - GNUNET_assert (NULL != denominations_by_group); + donation_units_by_group = json_array (); + GNUNET_assert (NULL != donation_units_by_group); { struct GNUNET_CONTAINER_MultiHashMap *dbg; dbg = GNUNET_CONTAINER_multihashmap_create (128, false); - for (unsigned int i = 0; i<kd->num_denom_keys; i++) + for (unsigned int i = 0; i<kd->num_donation_unit_keys; i++) { - const struct TALER_DONAU_DenomPublicKey *dk = &kd->denom_keys[i]; - struct TALER_DenominationGroup meta = { - .cipher = dk->key.cipher, + const struct TALER_DonationUnitInformation *dk = &kd->donation_unit_keys[i]; + struct DONAU_DonationUnitGroup meta = { + .cipher = dk->key.bsign_pub_key->cipher, .value = dk->value, - .fees = dk->fees, - .age_mask = dk->key.age_mask + .year = dk->year }; struct GNUNET_HashCode key; struct GroupData *gd; - json_t *denom; + json_t *donation_unit; struct GNUNET_JSON_PackSpec key_spec; - if (GNUNET_TIME_timestamp_cmp (now, - >, - dk->expire_deposit)) - continue; /* skip keys that have expired */ - TALER_denomination_group_get_key (&meta, + //TODO: check year + + TALER_donation_unit_group_get_key (&meta, &key); gd = GNUNET_CONTAINER_multihashmap_get (dbg, &key); @@ -1621,28 +1523,28 @@ TALER_DONAU_keys_to_json (const struct TALER_DONAU_Keys *kd) } /* Build the running xor of the SHA512-hash of the public keys */ - GNUNET_CRYPTO_hash_xor (&dk->h_key.hash, + /*GNUNET_CRYPTO_hash_xor (&dk->h_key.hash, &gd->meta.hash, - &gd->meta.hash); + &gd->meta.hash);*/ switch (meta.cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_RSA: key_spec = GNUNET_JSON_pack_rsa_public_key ( "rsa_pub", - dk->key.details.rsa_public_key); + dk->key.bsign_pub_key->details.rsa_public_key); break; - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: key_spec = GNUNET_JSON_pack_data_varsize ( "cs_pub", - &dk->key.details.cs_public_key, - sizeof (dk->key.details.cs_public_key)); + &dk->key.bsign_pub_key->details.cs_public_key, + sizeof (dk->key.bsign_pub_key->details.cs_public_key)); break; default: GNUNET_assert (false); } - denom = GNUNET_JSON_PACK ( + donation_unit = GNUNET_JSON_PACK ( GNUNET_JSON_pack_timestamp ("stamp_expire_deposit", dk->expire_deposit), GNUNET_JSON_pack_timestamp ("stamp_expire_withdraw", @@ -1657,192 +1559,14 @@ TALER_DONAU_keys_to_json (const struct TALER_DONAU_Keys *kd) ); GNUNET_assert (0 == json_array_append_new (gd->json, - denom)); + donation_unit)); } GNUNET_CONTAINER_multihashmap_iterate (dbg, &add_grp, - denominations_by_group); + donation_unit_by_group); GNUNET_CONTAINER_multihashmap_destroy (dbg); } - auditors = json_array (); - GNUNET_assert (NULL != auditors); - for (unsigned int i = 0; i<kd->num_auditors; i++) - { - const struct TALER_DONAU_AuditorInformation *ai = &kd->auditors[i]; - json_t *a; - json_t *adenoms; - - adenoms = json_array (); - GNUNET_assert (NULL != adenoms); - for (unsigned int j = 0; j<ai->num_denom_keys; j++) - { - const struct TALER_DONAU_AuditorDenominationInfo *adi = - &ai->denom_keys[j]; - const struct TALER_DONAU_DenomPublicKey *dk = - &kd->denom_keys[adi->denom_key_offset]; - json_t *k; - - GNUNET_assert (adi->denom_key_offset < kd->num_denom_keys); - if (GNUNET_TIME_timestamp_cmp (now, - >, - dk->expire_deposit)) - continue; /* skip auditor signatures for denomination keys that have expired */ - GNUNET_assert (adi->denom_key_offset < kd->num_denom_keys); - k = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_data_auto ("denom_pub_h", - &dk->h_key), - GNUNET_JSON_pack_data_auto ("auditor_sig", - &adi->auditor_sig)); - GNUNET_assert (0 == - json_array_append_new (adenoms, - k)); - } - - a = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_data_auto ("auditor_pub", - &ai->auditor_pub), - GNUNET_JSON_pack_string ("auditor_url", - ai->auditor_url), - GNUNET_JSON_pack_array_steal ("denomination_keys", - adenoms)); - GNUNET_assert (0 == - json_array_append_new (auditors, - a)); - } - - global_fees = json_array (); - GNUNET_assert (NULL != global_fees); - for (unsigned int i = 0; i<kd->num_global_fees; i++) - { - const struct TALER_DONAU_GlobalFee *gf - = &kd->global_fees[i]; - - if (GNUNET_TIME_absolute_is_past (gf->end_date.abs_time)) - continue; - GNUNET_assert ( - 0 == - json_array_append_new ( - global_fees, - GNUNET_JSON_PACK ( - GNUNET_JSON_pack_timestamp ("start_date", - gf->start_date), - GNUNET_JSON_pack_timestamp ("end_date", - gf->end_date), - TALER_JSON_PACK_GLOBAL_FEES (&gf->fees), - GNUNET_JSON_pack_time_rel ("history_expiration", - gf->history_expiration), - GNUNET_JSON_pack_time_rel ("purse_timeout", - gf->purse_timeout), - GNUNET_JSON_pack_uint64 ("purse_account_limit", - gf->purse_account_limit), - GNUNET_JSON_pack_data_auto ("master_sig", - &gf->master_sig)))); - } - - accounts = json_array (); - GNUNET_assert (NULL != accounts); - for (unsigned int i = 0; i<kd->accounts_len; i++) - { - const struct TALER_DONAU_WireAccount *acc - = &kd->accounts[i]; - json_t *credit_restrictions; - json_t *debit_restrictions; - - credit_restrictions - = ar_to_json (acc->credit_restrictions_length, - acc->credit_restrictions); - GNUNET_assert (NULL != credit_restrictions); - debit_restrictions - = ar_to_json (acc->debit_restrictions_length, - acc->debit_restrictions); - GNUNET_assert (NULL != debit_restrictions); - GNUNET_assert ( - 0 == - json_array_append_new ( - accounts, - GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("payto_uri", - acc->payto_uri), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_string ("conversion_url", - acc->conversion_url)), - GNUNET_JSON_pack_array_steal ("debit_restrictions", - debit_restrictions), - GNUNET_JSON_pack_array_steal ("credit_restrictions", - credit_restrictions), - GNUNET_JSON_pack_data_auto ("master_sig", - &acc->master_sig)))); - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Serialized %u/%u wire accounts to JSON\n", - (unsigned int) json_array_size (accounts), - kd->accounts_len); - - wire_fees = json_object (); - GNUNET_assert (NULL != wire_fees); - for (unsigned int i = 0; i<kd->fees_len; i++) - { - const struct TALER_DONAU_WireFeesByMethod *fbw - = &kd->fees[i]; - json_t *wf; - - wf = json_array (); - GNUNET_assert (NULL != wf); - for (struct TALER_DONAU_WireAggregateFees *p = fbw->fees_head; - NULL != p; - p = p->next) - { - GNUNET_assert ( - 0 == - json_array_append_new ( - wf, - GNUNET_JSON_PACK ( - TALER_JSON_pack_amount ("wire_fee", - &p->fees.wire), - TALER_JSON_pack_amount ("closing_fee", - &p->fees.closing), - GNUNET_JSON_pack_timestamp ("start_date", - p->start_date), - GNUNET_JSON_pack_timestamp ("end_date", - p->end_date), - GNUNET_JSON_pack_data_auto ("sig", - &p->master_sig)))); - } - GNUNET_assert (0 == - json_object_set_new (wire_fees, - fbw->method, - wf)); - } - - recoup = json_array (); - GNUNET_assert (NULL != recoup); - for (unsigned int i = 0; i<kd->num_denom_keys; i++) - { - const struct TALER_DONAU_DenomPublicKey *dk - = &kd->denom_keys[i]; - if (! dk->revoked) - continue; - GNUNET_assert (0 == - json_array_append_new ( - recoup, - GNUNET_JSON_PACK ( - GNUNET_JSON_pack_data_auto ("h_denom_pub", - &dk->h_key)))); - } - - wblwk = json_array (); - GNUNET_assert (NULL != wblwk); - for (unsigned int i = 0; i<kd->wblwk_length; i++) - { - const struct TALER_Amount *a = &kd->wallet_balance_limit_without_kyc[i]; - - GNUNET_assert (0 == - json_array_append_new ( - wblwk, - TALER_JSON_from_amount (a))); - } - keys = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("version", kd->version), @@ -1850,59 +1574,14 @@ TALER_DONAU_keys_to_json (const struct TALER_DONAU_Keys *kd) kd->currency), GNUNET_JSON_pack_uint64 ("currency_fraction_digits", kd->currency_fraction_digits), - TALER_JSON_pack_amount ("stefan_abs", - &kd->stefan_abs), - TALER_JSON_pack_amount ("stefan_log", - &kd->stefan_log), - TALER_JSON_pack_amount ("stefan_lin", - &kd->stefan_lin), - GNUNET_JSON_pack_string ("asset_type", - kd->asset_type), - GNUNET_JSON_pack_data_auto ("master_public_key", - &kd->master_pub), - GNUNET_JSON_pack_time_rel ("reserve_closing_delay", - kd->reserve_closing_delay), - GNUNET_JSON_pack_timestamp ("list_issue_date", - kd->list_issue_date), - GNUNET_JSON_pack_array_steal ("global_fees", - global_fees), GNUNET_JSON_pack_array_steal ("signkeys", signkeys), - GNUNET_JSON_pack_object_steal ("wire_fees", - wire_fees), - GNUNET_JSON_pack_array_steal ("accounts", - accounts), - GNUNET_JSON_pack_array_steal ("wads", - json_array ()), - GNUNET_JSON_pack_array_steal ("denominations", - denominations_by_group), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_array_steal ("recoup", - recoup)), - GNUNET_JSON_pack_array_steal ("auditors", - auditors), - GNUNET_JSON_pack_bool ("rewards_allowed", - kd->rewards_allowed), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_object_incref ("extensions", - kd->extensions)), - GNUNET_JSON_pack_allow_null ( - GNUNET_is_zero (&kd->extensions_sig) - ? GNUNET_JSON_pack_string ("dummy", - NULL) - : GNUNET_JSON_pack_data_auto ("extensions_sig", - &kd->extensions_sig)), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_array_steal ("wallet_balance_limit_without_kyc", - wblwk)) - + GNUNET_JSON_pack_array_steal ("donation_units", + donation_units_by_group) ); return GNUNET_JSON_PACK ( GNUNET_JSON_pack_uint64 ("version", DONAU_SERIALIZATION_FORMAT_VERSION), - GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_timestamp ("expire", - kd->key_data_expiration)), GNUNET_JSON_pack_string ("donau_url", kd->donau_url), GNUNET_JSON_pack_object_steal ("keys", diff --git a/src/util/donau_crypto.c b/src/util/donau_crypto.c @@ -0,0 +1,62 @@ +/* + This file is part of TALER + Copyright (C) 2014-2022 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> +*/ +/** + * @file util/donau_crypto.c + * @brief Cryptographic utility functions + * @author Lukas Matyja + */ +#include <taler/platform.h> +#include <taler/taler_util.h> +#include "donau_util.h" +#include <gcrypt.h> + +GNUNET_NETWORK_STRUCT_BEGIN +/** + * Structure we hash to compute the group key for + * a donation unit group. + */ +struct DonationUnitGroupP +{ + /** + * Value of coins in this denomination group. + */ + struct TALER_AmountNBO value; + + /** + * Cipher used for the donation unit, in NBO. + */ + uint32_t cipher GNUNET_PACKED; +}; +GNUNET_NETWORK_STRUCT_END + + + +void +TALER_donation_unit_group_get_key ( + const struct DonationUnitGroupP *dg, + struct GNUNET_HashCode *key) +{ + struct DonationUnitGroupP dgp = { + .cipher = htonl (dg->cipher) + }; + + TALER_amount_hton (&dgp.value, + &dg->value); + GNUNET_CRYPTO_hash (&dgp, + sizeof (dgp), + key); +} +