From 632d17f642561f4526f8c22f503a001069dcaf84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96zg=C3=BCr=20Kesim?= Date: Mon, 7 Feb 2022 18:39:58 +0100 Subject: [PATCH] [WIP] moving towards withdrawal with age restriction Age_mask now taken into account when denominations are being setup. However, tests fail, because denoms can't be found!? Probably because on initial generation of the denominations, the age mask is not setup, yet, because age restriction hasn't been enabled yet!? --- src/exchange-tools/taler-exchange-offline.c | 65 ++++++++++++++++--- ...ler-exchange-httpd_management_extensions.c | 5 +- src/extensions/extension_age_restriction.c | 4 +- src/include/taler_exchange_service.h | 7 -- src/lib/exchange_api_handle.c | 10 ++- src/lib/exchange_api_management_get_keys.c | 2 +- src/lib/exchange_api_withdraw.c | 5 +- src/testing/testing_api_cmd_refresh.c | 9 ++- src/testing/testing_api_cmd_withdraw.c | 2 +- src/testing/testing_api_helpers_exchange.c | 4 +- 10 files changed, 83 insertions(+), 30 deletions(-) diff --git a/src/exchange-tools/taler-exchange-offline.c b/src/exchange-tools/taler-exchange-offline.c index 25e434f9f..b7be2ddaa 100644 --- a/src/exchange-tools/taler-exchange-offline.c +++ b/src/exchange-tools/taler-exchange-offline.c @@ -152,6 +152,10 @@ static char *currency; */ static char *CFG_exchange_url; +/** + * If age restriction is enabled, the age mask to be used + */ +static struct TALER_AgeMask age_mask = {0}; /** * A subcommand supported by this program. @@ -3198,6 +3202,43 @@ sign_signkeys (const struct TALER_SecurityModulePublicKeyP *secm_pub, } +/** + * Looks up the AGE_RESTRICTED setting for a denomination in the config and + * returns the age restriction (mask) accordingly. + * + * @param section_name Section in the configuration for the particular + * denomination. + */ +static struct TALER_AgeMask +load_age_mask (const char*section_name) +{ + static const struct TALER_AgeMask null_mask = {0}; + enum GNUNET_GenericReturnValue ret; + + if (age_mask.mask == 0) + return null_mask; + + if (GNUNET_OK != (GNUNET_CONFIGURATION_have_value ( + kcfg, + section_name, + "AGE_RESTRICTED"))) + return null_mask; + + ret = GNUNET_CONFIGURATION_get_value_yesno (kcfg, + section_name, + "AGE_RESTRICTED"); + if (GNUNET_YES == ret) + return age_mask; + + if (GNUNET_SYSERR == ret) + GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, + section_name, + "AGE_RESTRICTED", + "Value must be YES or NO\n"); + return null_mask; +} + + /** * Sign @a denomkeys with offline key. * @@ -3286,7 +3327,10 @@ sign_denomkeys (const struct TALER_SecurityModulePublicKeyP *secm_pub, duration = GNUNET_TIME_absolute_get_difference ( stamp_start.abs_time, stamp_expire_withdraw.abs_time); - // FIXME-Oec: setup age mask here? + + /* Load the age mask, if applicable to this denomination */ + denom_pub.age_mask = load_age_mask (section_name); + TALER_denom_pub_hash (&denom_pub, &h_denom_pub); switch (denom_pub.cipher) @@ -3520,14 +3564,6 @@ do_extensions_show (char *const *args) json_t *exts = json_object (); const struct TALER_Extension *it; - TALER_extensions_init (); - if (GNUNET_OK != TALER_extensions_load_taler_config (kcfg)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "error while loading taler config for extensions\n"); - return; - } - for (it = TALER_extensions_get_head (); NULL != it; it = it->next) @@ -3781,6 +3817,17 @@ run (void *cls, global_ret = EXIT_NOTCONFIGURED; return; } + + /* load age mask, if age restriction is enabled */ + TALER_extensions_init (); + if (GNUNET_OK != TALER_extensions_load_taler_config (kcfg)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "error while loading taler config for extensions\n"); + return; + } + age_mask = TALER_extensions_age_restriction_ageMask (); + ctx = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule, &rc); rc = GNUNET_CURL_gnunet_rc_create (ctx); diff --git a/src/exchange/taler-exchange-httpd_management_extensions.c b/src/exchange/taler-exchange-httpd_management_extensions.c index ca009f60d..d24a9847f 100644 --- a/src/exchange/taler-exchange-httpd_management_extensions.c +++ b/src/exchange/taler-exchange-httpd_management_extensions.c @@ -31,7 +31,6 @@ #include "taler_extensions.h" #include "taler_dbevents.h" - /** * Extension carries the necessary data for a particular extension. * @@ -295,6 +294,10 @@ TEH_handler_management_post_extensions ( NULL, 0); + + /* FIXME-oec. Because of a change of extensions, the key might */ + TEH_keys_update_states (); + CLEANUP: for (unsigned int i = 0; i < sec.num_extensions; i++) { diff --git a/src/extensions/extension_age_restriction.c b/src/extensions/extension_age_restriction.c index 1846bcf86..8005b2ffe 100644 --- a/src/extensions/extension_age_restriction.c +++ b/src/extensions/extension_age_restriction.c @@ -224,8 +224,8 @@ age_restriction_load_taler_config ( if (GNUNET_OK == ret) { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "settings age mask to %x with #groups: %d\n", mask.mask, + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "setting age mask to %x with #groups: %d\n", mask.mask, __builtin_popcount (mask.mask) - 1); _config.mask.mask = mask.mask; _config.num_groups = __builtin_popcount (mask.mask) - 1; /* no underflow, first bit always set */ diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index 49dcfae40..661918ce1 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -159,13 +159,6 @@ struct TALER_EXCHANGE_DenomPublicKey * revoked by the exchange. */ bool revoked; - - /** - * If age_mask non-zero, the denomination is age-restricted, with the age - * groups as defined in the mask. - */ - struct TALER_AgeMask age_mask; - bool age_restricted; }; diff --git a/src/lib/exchange_api_handle.c b/src/lib/exchange_api_handle.c index 26c0c5d53..8d8e71c4d 100644 --- a/src/lib/exchange_api_handle.c +++ b/src/lib/exchange_api_handle.c @@ -364,6 +364,9 @@ parse_json_denomkey (struct TALER_EXCHANGE_DenomPublicKey *denom_key, sizeof (struct GNUNET_HashCode)); if (! check_sigs) return GNUNET_OK; + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "XXXXX checking validity of %s with age_mask %d\n", GNUNET_h2s ( + &denom_key->h_key.hash), denom_key->key.age_mask.mask); EXITIF (GNUNET_SYSERR == TALER_exchange_offline_denom_validity_verify ( &denom_key->h_key, @@ -378,6 +381,8 @@ parse_json_denomkey (struct TALER_EXCHANGE_DenomPublicKey *denom_key, &denom_key->fee_refund, master_key, &denom_key->master_sig)); + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "XXXXX validity of %s OK\n", + GNUNET_h2s (&denom_key->h_key.hash)); return GNUNET_OK; EXITIF_exit: /* invalidate denom_key, just to be sure */ @@ -890,8 +895,9 @@ decode_keys_json (const json_t *resp_obj, * "denoms" or "age_restricted_denoms" */ if (hive[s].is_optional_age_restriction) { - dk.age_restricted = true; - dk.age_mask.mask = key_data->age_mask.mask; + // dk.age_restricted = true; + // dk.age_mask.mask = key_data->age_mask.mask; + GNUNET_assert (0 != key_data->age_mask.mask); } for (unsigned int j = 0; diff --git a/src/lib/exchange_api_management_get_keys.c b/src/lib/exchange_api_management_get_keys.c index e776082d3..1b6e0db8c 100644 --- a/src/lib/exchange_api_management_get_keys.c +++ b/src/lib/exchange_api_management_get_keys.c @@ -32,7 +32,7 @@ /** * Set to 1 for extra debug logging. */ -#define DEBUG 0 +#define DEBUG 1 /* FIXME-oec */ /** diff --git a/src/lib/exchange_api_withdraw.c b/src/lib/exchange_api_withdraw.c index d0ac857f3..e3dd8d130 100644 --- a/src/lib/exchange_api_withdraw.c +++ b/src/lib/exchange_api_withdraw.c @@ -184,6 +184,7 @@ TALER_EXCHANGE_withdraw ( { struct TALER_PlanchetDetail pd; struct TALER_EXCHANGE_WithdrawHandle *wh; + bool age_restricted = (0 != pk->key.age_mask.mask); wh = GNUNET_new (struct TALER_EXCHANGE_WithdrawHandle); wh->exchange = exchange; @@ -193,8 +194,8 @@ TALER_EXCHANGE_withdraw ( wh->ps = *ps; wh->ach = ach; - GNUNET_assert ( (pk->age_restricted && (NULL != ach)) || - (! pk->age_restricted && (NULL == ach)) ); + GNUNET_assert ( (age_restricted && (NULL != ach)) || + (! age_restricted && (NULL == ach))); if (GNUNET_OK != TALER_planchet_prepare (&pk->key, diff --git a/src/testing/testing_api_cmd_refresh.c b/src/testing/testing_api_cmd_refresh.c index 2f977f517..76294f8e8 100644 --- a/src/testing/testing_api_cmd_refresh.c +++ b/src/testing/testing_api_cmd_refresh.c @@ -997,6 +997,7 @@ melt_run (void *cls, const struct TALER_DenominationSignature *melt_sig; const struct TALER_EXCHANGE_DenomPublicKey *melt_denom_pub; const struct TALER_TESTING_Command *coin_command; + bool age_restricted; if (NULL == (coin_command = TALER_TESTING_interpreter_lookup_command @@ -1026,6 +1027,7 @@ melt_run (void *cls, TALER_TESTING_interpreter_fail (rms->is); return; } + if (GNUNET_OK != TALER_TESTING_get_trait_denom_pub (coin_command, 0, @@ -1035,9 +1037,11 @@ melt_run (void *cls, TALER_TESTING_interpreter_fail (rms->is); return; } + /* Melt amount starts with the melt fee of the old coin; we'll add the values and withdraw fees of the fresh coins next */ melt_amount = melt_denom_pub->fee_refresh; + age_restricted = melt_denom_pub->key.age_mask.mask != 0; for (unsigned int i = 0; iexchange), &fresh_amount, - melt_denom_pub->age_restricted); + age_restricted); if (NULL == fresh_pk) { GNUNET_break (0); @@ -1080,8 +1084,7 @@ melt_run (void *cls, { struct TALER_AgeCommitment *ac = NULL; - GNUNET_assert (melt_denom_pub->age_restricted == - (NULL != rms->age_commitment)); + GNUNET_assert (age_restricted == (NULL != rms->age_commitment)); if (NULL != rms->age_commitment) { diff --git a/src/testing/testing_api_cmd_withdraw.c b/src/testing/testing_api_cmd_withdraw.c index c6ba7d1a7..ebffaadc5 100644 --- a/src/testing/testing_api_cmd_withdraw.c +++ b/src/testing/testing_api_cmd_withdraw.c @@ -464,7 +464,7 @@ withdraw_run (void *cls, GNUNET_assert (GNUNET_OK == TALER_age_restriction_commit ( - &ws->pk->age_mask, + &ws->pk->key.age_mask, ws->age, seed, ac)); diff --git a/src/testing/testing_api_helpers_exchange.c b/src/testing/testing_api_helpers_exchange.c index 06531453f..55aa85531 100644 --- a/src/testing/testing_api_helpers_exchange.c +++ b/src/testing/testing_api_helpers_exchange.c @@ -441,7 +441,7 @@ TALER_TESTING_find_pk (const struct TALER_EXCHANGE_Keys *keys, (GNUNET_TIME_timestamp_cmp (now, <, pk->withdraw_valid_until)) && - (age_restricted == pk->age_restricted) ) + (age_restricted == (0 != pk->key.age_mask.mask)) ) return pk; } /* do 2nd pass to check if expiration times are to blame for @@ -458,7 +458,7 @@ TALER_TESTING_find_pk (const struct TALER_EXCHANGE_Keys *keys, GNUNET_TIME_timestamp_cmp (now, >, pk->withdraw_valid_until) ) && - (age_restricted == pk->age_restricted) ) + (age_restricted == (0 != pk->key.age_mask.mask)) ) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING,