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,