From 8bdf6ab19df70c16d335ecf82f2c3b2117eeb70e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96zg=C3=BCr=20Kesim?= Date: Wed, 16 Feb 2022 22:01:05 +0100 Subject: [age restriction] progress 14/n - withdraw and deposit Age restriction support for - withdraw is done and tested - deposit is done and tested TODOs: - melt/refresh/reveal - link ------ Added functions - TALER_age_restriction_commit - TALER_age_commitment_derive - TALER_age_commitment_hash - TALER_age_restriction_commitment_free_inside - Hash of age commitment passed around API boundaries Exchangedb adjustments for denominations - all prepared statements re: denominations now handle age_mask - signature parameters adjusted Hash and signature verification of /keys adjusted - Hashes of (normal) denominations and age-restricted denominations are calculated seperately - The hash of the age-restricted ones will then be added to the other hash - The total hash is signed/verified Tests for withdraw with age restriction added - TALER_EXCHANGE_DenomPublickey now carries age_mask - TALER_TESTING_cmd_withdraw_amount* takes age parameter - TALER_TESTING_find_pk takes boolean age_restricted - WithdrawState carries age_commitment and its hash - withdraw_run derives new age commitment, if applicable - Added age parameter to testing (13 as example) Various Fixes and changes - Fixes of post handler for /management/extensions - Fixes for offline tool extensions signing - Slight refactoring of extensions - Age restriction extension simplified - config is now global to extension - added global TEH_age_restriction_enabled and TEH_age_mask in taler-exchange-httpd - helper functions and macros introduced --- src/lib/exchange_api_handle.c | 58 +++++++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 22 deletions(-) (limited to 'src/lib/exchange_api_handle.c') diff --git a/src/lib/exchange_api_handle.c b/src/lib/exchange_api_handle.c index cf3d69d6a..3243f5e95 100644 --- a/src/lib/exchange_api_handle.c +++ b/src/lib/exchange_api_handle.c @@ -667,7 +667,9 @@ decode_keys_json (const json_t *resp_obj, enum TALER_EXCHANGE_VersionCompatibility *vc) { struct TALER_ExchangeSignatureP sig; - struct GNUNET_HashContext *hash_context; + struct GNUNET_HashContext *hash_context = NULL; + struct GNUNET_HashContext *hash_context_restricted = NULL; + bool have_age_restricted_denom = false; struct TALER_ExchangePublicKeyP pub; const char *currency; struct GNUNET_JSON_Specification mspec[] = { @@ -746,7 +748,6 @@ decode_keys_json (const json_t *resp_obj, key_data->version = GNUNET_strdup (ver); } - hash_context = NULL; EXITIF (GNUNET_OK != GNUNET_JSON_parse (resp_obj, (check_sig) ? mspec : &mspec[2], @@ -766,7 +767,10 @@ decode_keys_json (const json_t *resp_obj, /* parse the master public key and issue date of the response */ if (check_sig) + { hash_context = GNUNET_CRYPTO_hash_context_start (); + hash_context_restricted = GNUNET_CRYPTO_hash_context_start (); + } /* parse the signing keys */ { @@ -829,6 +833,9 @@ decode_keys_json (const json_t *resp_obj, EXITIF (GNUNET_OK != TALER_extensions_load_json_config (extensions)); } + + /* 4. assuming we might have now a new value for age_mask, set it in key_data */ + key_data->age_mask = TALER_extensions_age_restriction_ageMask (); } /* parse the denomination keys, merging with the @@ -839,9 +846,15 @@ decode_keys_json (const json_t *resp_obj, */ struct { char *name; - bool is_optional_age_restriction;} hive[2] = { - { "denoms", false }, - { "age_restricted_denoms", true }, + struct GNUNET_HashContext *hc; + bool is_optional_age_restriction;} + hive[2] = { + { "denoms", + hash_context, + false }, + { "age_restricted_denoms", + hash_context_restricted, + true } }; for (size_t s = 0; s < sizeof(hive) / sizeof(hive[0]); s++) @@ -853,25 +866,19 @@ decode_keys_json (const json_t *resp_obj, denom_keys_array = json_object_get (resp_obj, hive[s].name); - EXITIF (NULL == denom_keys_array && - ! hive[s].is_optional_age_restriction); - - if (NULL == denom_keys_array && - hive[s].is_optional_age_restriction) + if (NULL == denom_keys_array) continue; - /* if "age_restricted_denoms" exists, age-restriction better be enabled - * (that is: mask non-zero) */ - EXITIF (NULL != denom_keys_array && - hive[s].is_optional_age_restriction && - 0 == key_data->age_mask.mask); - EXITIF (JSON_ARRAY != json_typeof (denom_keys_array)); json_array_foreach (denom_keys_array, index, denom_key_obj) { struct TALER_EXCHANGE_DenomPublicKey dk; bool found = false; + /* mark that we have at least one age restricted denomination, needed + * for the hash calculation and signature verification below. */ + have_age_restricted_denom |= hive[s].is_optional_age_restriction; + memset (&dk, 0, sizeof (dk)); @@ -880,12 +887,7 @@ decode_keys_json (const json_t *resp_obj, check_sig, denom_key_obj, &key_data->master_pub, - hash_context)); - - /* Mark age restriction according where we got this denomination from, - * "denoms" or "age_restricted_denoms" */ - if (hive[s].is_optional_age_restriction) - dk.age_restricted = true; + hive[s].hc)); for (unsigned int j = 0; jnum_denom_keys; @@ -1044,6 +1046,18 @@ decode_keys_json (const json_t *resp_obj, .list_issue_date = GNUNET_TIME_timestamp_hton (key_data->list_issue_date) }; + /* If we had any age restricted denominations, add their hash to the end of + * the normal denominations. */ + if (have_age_restricted_denom) + { + struct GNUNET_HashCode hcr; + GNUNET_CRYPTO_hash_context_finish (hash_context_restricted, + &hcr); + GNUNET_CRYPTO_hash_context_read (hash_context, + &hcr, + sizeof(struct GNUNET_HashCode)); + } + GNUNET_CRYPTO_hash_context_finish (hash_context, &ks.hc); hash_context = NULL; -- cgit v1.2.3