Compare commits
4 Commits
1090389d6f
...
1b1a6c142a
Author | SHA1 | Date | |
---|---|---|---|
1b1a6c142a | |||
632d17f642 | |||
d02b5e213a | |||
f8b1c3f8db |
@ -152,6 +152,10 @@ static char *currency;
|
|||||||
*/
|
*/
|
||||||
static char *CFG_exchange_url;
|
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.
|
* A subcommand supported by this program.
|
||||||
@ -3037,6 +3041,7 @@ do_show (char *const *args)
|
|||||||
keys = parse_keys_input ("show");
|
keys = parse_keys_input ("show");
|
||||||
if (NULL == keys)
|
if (NULL == keys)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
load_offline_key (GNUNET_NO))
|
load_offline_key (GNUNET_NO))
|
||||||
return;
|
return;
|
||||||
@ -3197,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.
|
* Sign @a denomkeys with offline key.
|
||||||
*
|
*
|
||||||
@ -3285,7 +3327,10 @@ sign_denomkeys (const struct TALER_SecurityModulePublicKeyP *secm_pub,
|
|||||||
duration = GNUNET_TIME_absolute_get_difference (
|
duration = GNUNET_TIME_absolute_get_difference (
|
||||||
stamp_start.abs_time,
|
stamp_start.abs_time,
|
||||||
stamp_expire_withdraw.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,
|
TALER_denom_pub_hash (&denom_pub,
|
||||||
&h_denom_pub);
|
&h_denom_pub);
|
||||||
switch (denom_pub.cipher)
|
switch (denom_pub.cipher)
|
||||||
@ -3519,14 +3564,6 @@ do_extensions_show (char *const *args)
|
|||||||
json_t *exts = json_object ();
|
json_t *exts = json_object ();
|
||||||
const struct TALER_Extension *it;
|
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 ();
|
for (it = TALER_extensions_get_head ();
|
||||||
NULL != it;
|
NULL != it;
|
||||||
it = it->next)
|
it = it->next)
|
||||||
@ -3780,6 +3817,17 @@ run (void *cls,
|
|||||||
global_ret = EXIT_NOTCONFIGURED;
|
global_ret = EXIT_NOTCONFIGURED;
|
||||||
return;
|
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,
|
ctx = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule,
|
||||||
&rc);
|
&rc);
|
||||||
rc = GNUNET_CURL_gnunet_rc_create (ctx);
|
rc = GNUNET_CURL_gnunet_rc_create (ctx);
|
||||||
|
@ -157,6 +157,12 @@ TEH_extensions_init ()
|
|||||||
it = it->next)
|
it = it->next)
|
||||||
extension_update_event_cb (NULL, &it->type, sizeof(it->type));
|
extension_update_event_cb (NULL, &it->type, sizeof(it->type));
|
||||||
|
|
||||||
|
/* FIXME: shall we load the extensions from the config right away?
|
||||||
|
* We do have to for now, as otherwise denominations with age restriction
|
||||||
|
* will not have the age mask set right upon initial generation.
|
||||||
|
*/
|
||||||
|
TALER_extensions_load_taler_config (TEH_cfg);
|
||||||
|
|
||||||
return GNUNET_OK;
|
return GNUNET_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -743,43 +743,30 @@ static struct TALER_AgeMask
|
|||||||
load_age_mask (const char*section_name)
|
load_age_mask (const char*section_name)
|
||||||
{
|
{
|
||||||
static const struct TALER_AgeMask null_mask = {0};
|
static const struct TALER_AgeMask null_mask = {0};
|
||||||
struct TALER_AgeMask age_mask = {0};
|
enum GNUNET_GenericReturnValue ret;
|
||||||
/* TODO: optimize by putting this into global? */
|
struct TALER_AgeMask age_mask = TALER_extensions_age_restriction_ageMask ();
|
||||||
const struct TALER_Extension *age_ext =
|
|
||||||
TALER_extensions_get_by_type (TALER_Extension_AgeRestriction);
|
|
||||||
|
|
||||||
// Get the age mask from the extension, if configured
|
|
||||||
/* TODO: optimize by putting this into global? */
|
|
||||||
if (TALER_extensions_is_enabled (age_ext))
|
|
||||||
age_mask = *(struct TALER_AgeMask *) age_ext->config;
|
|
||||||
|
|
||||||
if (age_mask.mask == 0)
|
if (age_mask.mask == 0)
|
||||||
{
|
|
||||||
/* Age restriction support is not enabled. Ignore the AGE_RESTRICTED field
|
|
||||||
* for the particular denomination and simply return the null_mask
|
|
||||||
*/
|
|
||||||
return null_mask;
|
return null_mask;
|
||||||
}
|
|
||||||
|
|
||||||
if (GNUNET_OK == (GNUNET_CONFIGURATION_have_value (
|
if (GNUNET_OK != (GNUNET_CONFIGURATION_have_value (
|
||||||
TEH_cfg,
|
TEH_cfg,
|
||||||
section_name,
|
section_name,
|
||||||
"AGE_RESTRICTED")))
|
"AGE_RESTRICTED")))
|
||||||
{
|
return null_mask;
|
||||||
enum GNUNET_GenericReturnValue ret;
|
|
||||||
if (GNUNET_SYSERR == (ret = GNUNET_CONFIGURATION_get_value_yesno (TEH_cfg,
|
|
||||||
section_name,
|
|
||||||
"AGE_RESTRICTED")))
|
|
||||||
{
|
|
||||||
GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
|
|
||||||
section_name,
|
|
||||||
"AGE_RESTRICTED",
|
|
||||||
"Value must be YES or NO\n");
|
|
||||||
return null_mask;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return age_mask;
|
ret = GNUNET_CONFIGURATION_get_value_yesno (TEH_cfg,
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1187,6 +1174,8 @@ denomination_info_cb (
|
|||||||
dk->meta = *meta;
|
dk->meta = *meta;
|
||||||
dk->master_sig = *master_sig;
|
dk->master_sig = *master_sig;
|
||||||
dk->recoup_possible = recoup_possible;
|
dk->recoup_possible = recoup_possible;
|
||||||
|
dk->denom_pub.age_mask = meta->age_mask;
|
||||||
|
|
||||||
GNUNET_assert (
|
GNUNET_assert (
|
||||||
GNUNET_OK ==
|
GNUNET_OK ==
|
||||||
GNUNET_CONTAINER_multihashmap_put (ksh->denomkey_map,
|
GNUNET_CONTAINER_multihashmap_put (ksh->denomkey_map,
|
||||||
@ -1601,7 +1590,7 @@ setup_general_response_headers (struct TEH_KeyStateHandle *ksh,
|
|||||||
* @a recoup and @a denoms.
|
* @a recoup and @a denoms.
|
||||||
*
|
*
|
||||||
* @param[in,out] ksh key state handle we build @a krd for
|
* @param[in,out] ksh key state handle we build @a krd for
|
||||||
* @param[in] denom_keys_hash hash over all the denominatoin keys in @a denoms
|
* @param[in] denom_keys_hash hash over all the denominatoin keys in @a denoms and age_restricted_denoms
|
||||||
* @param last_cpd timestamp to use
|
* @param last_cpd timestamp to use
|
||||||
* @param signkeys list of sign keys to return
|
* @param signkeys list of sign keys to return
|
||||||
* @param recoup list of revoked keys to return
|
* @param recoup list of revoked keys to return
|
||||||
@ -1771,7 +1760,7 @@ create_krd (struct TEH_KeyStateHandle *ksh,
|
|||||||
GNUNET_assert (0 == r);
|
GNUNET_assert (0 == r);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Special case for age restrictions: if enabled, provide the lits of
|
// Special case for age restrictions: if enabled, provide the list of
|
||||||
// age-restricted denominations.
|
// age-restricted denominations.
|
||||||
if (age_restriction_enabled &&
|
if (age_restriction_enabled &&
|
||||||
NULL != age_restricted_denoms)
|
NULL != age_restricted_denoms)
|
||||||
@ -1857,9 +1846,11 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
|
|||||||
json_t *age_restricted_denoms = NULL;
|
json_t *age_restricted_denoms = NULL;
|
||||||
struct GNUNET_TIME_Timestamp last_cpd;
|
struct GNUNET_TIME_Timestamp last_cpd;
|
||||||
struct GNUNET_CONTAINER_Heap *heap;
|
struct GNUNET_CONTAINER_Heap *heap;
|
||||||
struct GNUNET_HashContext *hash_context;
|
struct GNUNET_HashContext *hash_context = NULL;
|
||||||
|
struct GNUNET_HashContext *hash_context_restricted = NULL;
|
||||||
bool age_restriction_active =
|
bool age_restriction_active =
|
||||||
TALER_extensions_is_enabled_type (TALER_Extension_AgeRestriction);
|
TALER_extensions_is_enabled_type (TALER_Extension_AgeRestriction);
|
||||||
|
bool have_age_restricted_denoms = false;
|
||||||
|
|
||||||
sctx.signkeys = json_array ();
|
sctx.signkeys = json_array ();
|
||||||
GNUNET_assert (NULL != sctx.signkeys);
|
GNUNET_assert (NULL != sctx.signkeys);
|
||||||
@ -1884,19 +1875,24 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
|
|||||||
= GNUNET_TIME_relative_min (dkc.min_dk_frequency,
|
= GNUNET_TIME_relative_min (dkc.min_dk_frequency,
|
||||||
sctx.min_sk_frequency);
|
sctx.min_sk_frequency);
|
||||||
}
|
}
|
||||||
|
|
||||||
denoms = json_array ();
|
denoms = json_array ();
|
||||||
GNUNET_assert (NULL != denoms);
|
GNUNET_assert (NULL != denoms);
|
||||||
|
hash_context = GNUNET_CRYPTO_hash_context_start ();
|
||||||
|
|
||||||
// If age restriction is enabled, initialize the array of age restricted denoms.
|
/* If age restriction is enabled, initialize the array of age restricted
|
||||||
/* TODO: optimize by putting this into global? */
|
denoms and prepare a hash for them, separate from the others. We will join
|
||||||
|
those hashes afterwards.*/
|
||||||
if (age_restriction_active)
|
if (age_restriction_active)
|
||||||
{
|
{
|
||||||
age_restricted_denoms = json_array ();
|
age_restricted_denoms = json_array ();
|
||||||
GNUNET_assert (NULL != age_restricted_denoms);
|
GNUNET_assert (NULL != age_restricted_denoms);
|
||||||
|
|
||||||
|
hash_context_restricted = GNUNET_CRYPTO_hash_context_start ();
|
||||||
}
|
}
|
||||||
|
|
||||||
last_cpd = GNUNET_TIME_UNIT_ZERO_TS;
|
last_cpd = GNUNET_TIME_UNIT_ZERO_TS;
|
||||||
hash_context = GNUNET_CRYPTO_hash_context_start ();
|
|
||||||
{
|
{
|
||||||
struct TEH_DenominationKey *dk;
|
struct TEH_DenominationKey *dk;
|
||||||
|
|
||||||
@ -1938,14 +1934,14 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
|
|||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
last_cpd = dk->meta.start;
|
last_cpd = dk->meta.start;
|
||||||
GNUNET_CRYPTO_hash_context_read (hash_context,
|
|
||||||
&dk->h_denom_pub,
|
|
||||||
sizeof (struct GNUNET_HashCode));
|
|
||||||
|
|
||||||
{
|
{
|
||||||
json_t *denom;
|
json_t *denom;
|
||||||
json_t *array;
|
json_t *array;
|
||||||
|
struct GNUNET_HashContext *hc;
|
||||||
|
|
||||||
|
|
||||||
denom =
|
denom =
|
||||||
GNUNET_JSON_PACK (
|
GNUNET_JSON_PACK (
|
||||||
@ -1972,19 +1968,25 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
|
|||||||
TALER_JSON_pack_amount ("fee_refund",
|
TALER_JSON_pack_amount ("fee_refund",
|
||||||
&dk->meta.fee_refund));
|
&dk->meta.fee_refund));
|
||||||
|
|
||||||
/* Put the denom into the correct array - denoms or age_restricted_denoms -
|
/* Put the denom into the correct array depending on the settings and
|
||||||
* depending on the settings and the properties of the denomination */
|
* the properties of the denomination. Also, we build up the right
|
||||||
|
* hash for the corresponding array. */
|
||||||
if (age_restriction_active &&
|
if (age_restriction_active &&
|
||||||
(0 != dk->denom_pub.age_mask.mask))
|
(0 != dk->denom_pub.age_mask.mask))
|
||||||
{
|
{
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
have_age_restricted_denoms = true;
|
||||||
"got agerestricted denom %p with mask %d\n",
|
|
||||||
&dk->denom_pub,
|
|
||||||
dk->denom_pub.age_mask.mask);
|
|
||||||
array = age_restricted_denoms;
|
array = age_restricted_denoms;
|
||||||
|
hc = hash_context_restricted;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
array = denoms;
|
array = denoms;
|
||||||
|
hc = hash_context;
|
||||||
|
}
|
||||||
|
|
||||||
|
GNUNET_CRYPTO_hash_context_read (hc,
|
||||||
|
&dk->h_denom_pub,
|
||||||
|
sizeof (struct GNUNET_HashCode));
|
||||||
|
|
||||||
GNUNET_assert (
|
GNUNET_assert (
|
||||||
0 ==
|
0 ==
|
||||||
@ -2000,8 +2002,21 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
|
|||||||
{
|
{
|
||||||
struct GNUNET_HashCode hc;
|
struct GNUNET_HashCode hc;
|
||||||
|
|
||||||
|
/* If age restriction is active and we had at least one denomination of
|
||||||
|
* that sort, we simply add the hash of all age restricted denominations at
|
||||||
|
* the end of the others. */
|
||||||
|
if (age_restriction_active && have_age_restricted_denoms)
|
||||||
|
{
|
||||||
|
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,
|
GNUNET_CRYPTO_hash_context_finish (hash_context,
|
||||||
&hc);
|
&hc);
|
||||||
|
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
create_krd (ksh,
|
create_krd (ksh,
|
||||||
&hc,
|
&hc,
|
||||||
@ -2672,7 +2687,9 @@ load_extension_data (const char *section_name,
|
|||||||
TEH_currency);
|
TEH_currency);
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
meta->age_restrictions = load_age_mask (section_name);
|
|
||||||
|
meta->age_mask = load_age_mask (section_name);
|
||||||
|
|
||||||
return GNUNET_OK;
|
return GNUNET_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2799,7 +2816,7 @@ add_future_denomkey_cb (void *cls,
|
|||||||
struct FutureBuilderContext *fbc = cls;
|
struct FutureBuilderContext *fbc = cls;
|
||||||
struct HelperDenomination *hd = value;
|
struct HelperDenomination *hd = value;
|
||||||
struct TEH_DenominationKey *dk;
|
struct TEH_DenominationKey *dk;
|
||||||
struct TALER_EXCHANGEDB_DenominationKeyMetaData meta;
|
struct TALER_EXCHANGEDB_DenominationKeyMetaData meta = {0};
|
||||||
|
|
||||||
dk = GNUNET_CONTAINER_multihashmap_get (fbc->ksh->denomkey_map,
|
dk = GNUNET_CONTAINER_multihashmap_get (fbc->ksh->denomkey_map,
|
||||||
h_denom_pub);
|
h_denom_pub);
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
#include "taler_extensions.h"
|
#include "taler_extensions.h"
|
||||||
#include "taler_dbevents.h"
|
#include "taler_dbevents.h"
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extension carries the necessary data for a particular extension.
|
* Extension carries the necessary data for a particular extension.
|
||||||
*
|
*
|
||||||
@ -295,6 +294,10 @@ TEH_handler_management_post_extensions (
|
|||||||
NULL,
|
NULL,
|
||||||
0);
|
0);
|
||||||
|
|
||||||
|
|
||||||
|
/* FIXME-oec. Because of a change of extensions, the key might */
|
||||||
|
TEH_keys_update_states ();
|
||||||
|
|
||||||
CLEANUP:
|
CLEANUP:
|
||||||
for (unsigned int i = 0; i < sec.num_extensions; i++)
|
for (unsigned int i = 0; i < sec.num_extensions; i++)
|
||||||
{
|
{
|
||||||
|
@ -204,6 +204,7 @@ add_keys (void *cls,
|
|||||||
TALER_denom_pub_free (&denom_pub);
|
TALER_denom_pub_free (&denom_pub);
|
||||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_active)
|
if (is_active)
|
||||||
{
|
{
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
@ -211,6 +212,7 @@ add_keys (void *cls,
|
|||||||
GNUNET_h2s (&d->h_denom_pub.hash));
|
GNUNET_h2s (&d->h_denom_pub.hash));
|
||||||
continue; /* skip, already known */
|
continue; /* skip, already known */
|
||||||
}
|
}
|
||||||
|
|
||||||
qs = TEH_plugin->add_denomination_key (
|
qs = TEH_plugin->add_denomination_key (
|
||||||
TEH_plugin->cls,
|
TEH_plugin->cls,
|
||||||
&d->h_denom_pub,
|
&d->h_denom_pub,
|
||||||
|
@ -25,7 +25,7 @@ CREATE TABLE IF NOT EXISTS denominations
|
|||||||
(denominations_serial BIGSERIAL UNIQUE
|
(denominations_serial BIGSERIAL UNIQUE
|
||||||
,denom_pub_hash BYTEA PRIMARY KEY CHECK (LENGTH(denom_pub_hash)=64)
|
,denom_pub_hash BYTEA PRIMARY KEY CHECK (LENGTH(denom_pub_hash)=64)
|
||||||
,denom_type INT4 NOT NULL DEFAULT (1) -- 1 == RSA (for now, remove default later!)
|
,denom_type INT4 NOT NULL DEFAULT (1) -- 1 == RSA (for now, remove default later!)
|
||||||
,age_restrictions INT4 NOT NULL DEFAULT (0)
|
,age_mask INT4 NOT NULL DEFAULT (0)
|
||||||
,denom_pub BYTEA NOT NULL
|
,denom_pub BYTEA NOT NULL
|
||||||
,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64)
|
,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64)
|
||||||
,valid_from INT8 NOT NULL
|
,valid_from INT8 NOT NULL
|
||||||
@ -47,7 +47,7 @@ COMMENT ON TABLE denominations
|
|||||||
IS 'Main denominations table. All the valid denominations the exchange knows about.';
|
IS 'Main denominations table. All the valid denominations the exchange knows about.';
|
||||||
COMMENT ON COLUMN denominations.denom_type
|
COMMENT ON COLUMN denominations.denom_type
|
||||||
IS 'determines cipher type for blind signatures used with this denomination; 0 is for RSA';
|
IS 'determines cipher type for blind signatures used with this denomination; 0 is for RSA';
|
||||||
COMMENT ON COLUMN denominations.age_restrictions
|
COMMENT ON COLUMN denominations.age_mask
|
||||||
IS 'bitmask with the age restrictions that are being used for this denomination; 0 if denomination does not support the use of age restrictions';
|
IS 'bitmask with the age restrictions that are being used for this denomination; 0 if denomination does not support the use of age restrictions';
|
||||||
COMMENT ON COLUMN denominations.denominations_serial
|
COMMENT ON COLUMN denominations.denominations_serial
|
||||||
IS 'needed for exchange-auditor replication logic';
|
IS 'needed for exchange-auditor replication logic';
|
||||||
|
@ -231,10 +231,11 @@ prepare_statements (struct PostgresClosure *pg)
|
|||||||
",fee_refresh_frac"
|
",fee_refresh_frac"
|
||||||
",fee_refund_val"
|
",fee_refund_val"
|
||||||
",fee_refund_frac"
|
",fee_refund_frac"
|
||||||
|
",age_mask"
|
||||||
") VALUES "
|
") VALUES "
|
||||||
"($1, $2, $3, $4, $5, $6, $7, $8, $9, $10,"
|
"($1, $2, $3, $4, $5, $6, $7, $8, $9, $10,"
|
||||||
" $11, $12, $13, $14, $15, $16, $17);",
|
" $11, $12, $13, $14, $15, $16, $17, $18);",
|
||||||
17),
|
18),
|
||||||
/* Used in #postgres_iterate_denomination_info() */
|
/* Used in #postgres_iterate_denomination_info() */
|
||||||
GNUNET_PQ_make_prepare (
|
GNUNET_PQ_make_prepare (
|
||||||
"denomination_iterate",
|
"denomination_iterate",
|
||||||
@ -255,6 +256,7 @@ prepare_statements (struct PostgresClosure *pg)
|
|||||||
",fee_refund_val"
|
",fee_refund_val"
|
||||||
",fee_refund_frac"
|
",fee_refund_frac"
|
||||||
",denom_pub"
|
",denom_pub"
|
||||||
|
",age_mask"
|
||||||
" FROM denominations;",
|
" FROM denominations;",
|
||||||
0),
|
0),
|
||||||
/* Used in #postgres_iterate_denominations() */
|
/* Used in #postgres_iterate_denominations() */
|
||||||
@ -278,6 +280,7 @@ prepare_statements (struct PostgresClosure *pg)
|
|||||||
",fee_refund_val"
|
",fee_refund_val"
|
||||||
",fee_refund_frac"
|
",fee_refund_frac"
|
||||||
",denom_pub"
|
",denom_pub"
|
||||||
|
",age_mask"
|
||||||
" FROM denominations"
|
" FROM denominations"
|
||||||
" LEFT JOIN "
|
" LEFT JOIN "
|
||||||
" denomination_revocations USING (denominations_serial);",
|
" denomination_revocations USING (denominations_serial);",
|
||||||
@ -341,6 +344,7 @@ prepare_statements (struct PostgresClosure *pg)
|
|||||||
",fee_refresh_frac"
|
",fee_refresh_frac"
|
||||||
",fee_refund_val"
|
",fee_refund_val"
|
||||||
",fee_refund_frac"
|
",fee_refund_frac"
|
||||||
|
",age_mask"
|
||||||
" FROM denominations"
|
" FROM denominations"
|
||||||
" WHERE denom_pub_hash=$1;",
|
" WHERE denom_pub_hash=$1;",
|
||||||
1),
|
1),
|
||||||
@ -2071,7 +2075,6 @@ prepare_statements (struct PostgresClosure *pg)
|
|||||||
"SELECT"
|
"SELECT"
|
||||||
" denominations_serial AS serial"
|
" denominations_serial AS serial"
|
||||||
",denom_type"
|
",denom_type"
|
||||||
",age_restrictions"
|
|
||||||
",denom_pub"
|
",denom_pub"
|
||||||
",master_sig"
|
",master_sig"
|
||||||
",valid_from"
|
",valid_from"
|
||||||
@ -2088,6 +2091,7 @@ prepare_statements (struct PostgresClosure *pg)
|
|||||||
",fee_refresh_frac"
|
",fee_refresh_frac"
|
||||||
",fee_refund_val"
|
",fee_refund_val"
|
||||||
",fee_refund_frac"
|
",fee_refund_frac"
|
||||||
|
",age_mask"
|
||||||
" FROM denominations"
|
" FROM denominations"
|
||||||
" WHERE denominations_serial > $1"
|
" WHERE denominations_serial > $1"
|
||||||
" ORDER BY denominations_serial ASC;",
|
" ORDER BY denominations_serial ASC;",
|
||||||
@ -2390,10 +2394,11 @@ prepare_statements (struct PostgresClosure *pg)
|
|||||||
",fee_refresh_frac"
|
",fee_refresh_frac"
|
||||||
",fee_refund_val"
|
",fee_refund_val"
|
||||||
",fee_refund_frac"
|
",fee_refund_frac"
|
||||||
|
",age_mask"
|
||||||
") VALUES "
|
") VALUES "
|
||||||
"($1, $2, $3, $4, $5, $6, $7, $8, $9, $10,"
|
"($1, $2, $3, $4, $5, $6, $7, $8, $9, $10,"
|
||||||
" $11, $12, $13, $14, $15, $16, $17, $18);",
|
" $11, $12, $13, $14, $15, $16, $17, $18, $19);",
|
||||||
18),
|
19),
|
||||||
GNUNET_PQ_make_prepare (
|
GNUNET_PQ_make_prepare (
|
||||||
"insert_into_table_denomination_revocations",
|
"insert_into_table_denomination_revocations",
|
||||||
"INSERT INTO denomination_revocations"
|
"INSERT INTO denomination_revocations"
|
||||||
@ -3096,9 +3101,12 @@ postgres_insert_denomination_info (
|
|||||||
TALER_PQ_query_param_amount_nbo (&issue->properties.fee_deposit),
|
TALER_PQ_query_param_amount_nbo (&issue->properties.fee_deposit),
|
||||||
TALER_PQ_query_param_amount_nbo (&issue->properties.fee_refresh),
|
TALER_PQ_query_param_amount_nbo (&issue->properties.fee_refresh),
|
||||||
TALER_PQ_query_param_amount_nbo (&issue->properties.fee_refund),
|
TALER_PQ_query_param_amount_nbo (&issue->properties.fee_refund),
|
||||||
|
GNUNET_PQ_query_param_uint32 (&denom_pub->age_mask.mask),
|
||||||
GNUNET_PQ_query_param_end
|
GNUNET_PQ_query_param_end
|
||||||
};
|
};
|
||||||
|
|
||||||
|
GNUNET_assert (denom_pub->age_mask.mask == issue->age_mask.mask);
|
||||||
|
|
||||||
GNUNET_assert (! GNUNET_TIME_absolute_is_zero (
|
GNUNET_assert (! GNUNET_TIME_absolute_is_zero (
|
||||||
GNUNET_TIME_timestamp_ntoh (
|
GNUNET_TIME_timestamp_ntoh (
|
||||||
issue->properties.start).abs_time));
|
issue->properties.start).abs_time));
|
||||||
@ -3172,6 +3180,8 @@ postgres_get_denomination_info (
|
|||||||
&issue->properties.fee_refresh),
|
&issue->properties.fee_refresh),
|
||||||
TALER_PQ_RESULT_SPEC_AMOUNT_NBO ("fee_refund",
|
TALER_PQ_RESULT_SPEC_AMOUNT_NBO ("fee_refund",
|
||||||
&issue->properties.fee_refund),
|
&issue->properties.fee_refund),
|
||||||
|
GNUNET_PQ_result_spec_uint32 ("age_mask",
|
||||||
|
&issue->age_mask.mask),
|
||||||
GNUNET_PQ_result_spec_end
|
GNUNET_PQ_result_spec_end
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -3258,12 +3268,15 @@ domination_cb_helper (void *cls,
|
|||||||
&issue.properties.fee_refund),
|
&issue.properties.fee_refund),
|
||||||
TALER_PQ_result_spec_denom_pub ("denom_pub",
|
TALER_PQ_result_spec_denom_pub ("denom_pub",
|
||||||
&denom_pub),
|
&denom_pub),
|
||||||
|
GNUNET_PQ_result_spec_uint32 ("age_mask",
|
||||||
|
&issue.age_mask.mask),
|
||||||
GNUNET_PQ_result_spec_end
|
GNUNET_PQ_result_spec_end
|
||||||
};
|
};
|
||||||
|
|
||||||
memset (&issue.properties.master,
|
memset (&issue.properties.master,
|
||||||
0,
|
0,
|
||||||
sizeof (issue.properties.master));
|
sizeof (issue.properties.master));
|
||||||
|
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
GNUNET_PQ_extract_result (result,
|
GNUNET_PQ_extract_result (result,
|
||||||
rs,
|
rs,
|
||||||
@ -3272,6 +3285,13 @@ domination_cb_helper (void *cls,
|
|||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Unfortunately we have to carry the age mask in both, the
|
||||||
|
* TALER_DenominationPublicKey and
|
||||||
|
* TALER_EXCHANGEDB_DenominationKeyInformationP at different times.
|
||||||
|
* Here we use _both_ so let's make sure the values are the same. */
|
||||||
|
denom_pub.age_mask = issue.age_mask;
|
||||||
|
|
||||||
issue.properties.purpose.size
|
issue.properties.purpose.size
|
||||||
= htonl (sizeof (struct TALER_DenominationKeyValidityPS));
|
= htonl (sizeof (struct TALER_DenominationKeyValidityPS));
|
||||||
issue.properties.purpose.purpose
|
issue.properties.purpose.purpose
|
||||||
@ -3357,10 +3377,10 @@ dominations_cb_helper (void *cls,
|
|||||||
|
|
||||||
for (unsigned int i = 0; i<num_results; i++)
|
for (unsigned int i = 0; i<num_results; i++)
|
||||||
{
|
{
|
||||||
struct TALER_EXCHANGEDB_DenominationKeyMetaData meta;
|
struct TALER_EXCHANGEDB_DenominationKeyMetaData meta = {0};
|
||||||
struct TALER_DenominationPublicKey denom_pub;
|
struct TALER_DenominationPublicKey denom_pub = {0};
|
||||||
struct TALER_MasterSignatureP master_sig;
|
struct TALER_MasterSignatureP master_sig = {0};
|
||||||
struct TALER_DenominationHash h_denom_pub;
|
struct TALER_DenominationHash h_denom_pub = {0};
|
||||||
bool revoked;
|
bool revoked;
|
||||||
struct GNUNET_PQ_ResultSpec rs[] = {
|
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||||
GNUNET_PQ_result_spec_auto_from_type ("master_sig",
|
GNUNET_PQ_result_spec_auto_from_type ("master_sig",
|
||||||
@ -3387,6 +3407,8 @@ dominations_cb_helper (void *cls,
|
|||||||
&meta.fee_refund),
|
&meta.fee_refund),
|
||||||
TALER_PQ_result_spec_denom_pub ("denom_pub",
|
TALER_PQ_result_spec_denom_pub ("denom_pub",
|
||||||
&denom_pub),
|
&denom_pub),
|
||||||
|
GNUNET_PQ_result_spec_uint32 ("age_mask",
|
||||||
|
&meta.age_mask.mask),
|
||||||
GNUNET_PQ_result_spec_end
|
GNUNET_PQ_result_spec_end
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -3398,6 +3420,10 @@ dominations_cb_helper (void *cls,
|
|||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* make sure the mask information is the same */
|
||||||
|
denom_pub.age_mask = meta.age_mask;
|
||||||
|
|
||||||
TALER_denom_pub_hash (&denom_pub,
|
TALER_denom_pub_hash (&denom_pub,
|
||||||
&h_denom_pub);
|
&h_denom_pub);
|
||||||
dic->cb (dic->cb_cls,
|
dic->cb (dic->cb_cls,
|
||||||
@ -10193,6 +10219,8 @@ postgres_lookup_denomination_key (
|
|||||||
&meta->fee_refresh),
|
&meta->fee_refresh),
|
||||||
TALER_PQ_RESULT_SPEC_AMOUNT ("fee_refund",
|
TALER_PQ_RESULT_SPEC_AMOUNT ("fee_refund",
|
||||||
&meta->fee_refund),
|
&meta->fee_refund),
|
||||||
|
GNUNET_PQ_result_spec_uint32 ("age_mask",
|
||||||
|
&meta->age_mask.mask),
|
||||||
GNUNET_PQ_result_spec_end
|
GNUNET_PQ_result_spec_end
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -10236,6 +10264,7 @@ postgres_add_denomination_key (
|
|||||||
TALER_PQ_query_param_amount (&meta->fee_deposit),
|
TALER_PQ_query_param_amount (&meta->fee_deposit),
|
||||||
TALER_PQ_query_param_amount (&meta->fee_refresh),
|
TALER_PQ_query_param_amount (&meta->fee_refresh),
|
||||||
TALER_PQ_query_param_amount (&meta->fee_refund),
|
TALER_PQ_query_param_amount (&meta->fee_refund),
|
||||||
|
GNUNET_PQ_query_param_uint32 (&meta->age_mask.mask),
|
||||||
GNUNET_PQ_query_param_end
|
GNUNET_PQ_query_param_end
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -224,6 +224,9 @@ age_restriction_load_taler_config (
|
|||||||
|
|
||||||
if (GNUNET_OK == ret)
|
if (GNUNET_OK == ret)
|
||||||
{
|
{
|
||||||
|
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.mask.mask = mask.mask;
|
||||||
_config.num_groups = __builtin_popcount (mask.mask) - 1; /* no underflow, first bit always set */
|
_config.num_groups = __builtin_popcount (mask.mask) - 1; /* no underflow, first bit always set */
|
||||||
this->config = &_config;
|
this->config = &_config;
|
||||||
@ -277,6 +280,10 @@ age_restriction_load_json_config (
|
|||||||
|
|
||||||
this->config_json = jconfig;
|
this->config_json = jconfig;
|
||||||
|
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||||
|
"loaded new age restriction config with age groups: %s\n",
|
||||||
|
TALER_age_mask_to_string (&mask));
|
||||||
|
|
||||||
return GNUNET_OK;
|
return GNUNET_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -350,6 +357,13 @@ TALER_extensions_age_restriction_enabled ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct TALER_AgeMask
|
||||||
|
TALER_extensions_age_restriction_ageMask ()
|
||||||
|
{
|
||||||
|
return _config.mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
TALER_extensions_age_restriction_num_groups ()
|
TALER_extensions_age_restriction_num_groups ()
|
||||||
{
|
{
|
||||||
|
@ -159,13 +159,6 @@ struct TALER_EXCHANGE_DenomPublicKey
|
|||||||
* revoked by the exchange.
|
* revoked by the exchange.
|
||||||
*/
|
*/
|
||||||
bool revoked;
|
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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -70,6 +70,12 @@ struct TALER_EXCHANGEDB_DenominationKeyInformationP
|
|||||||
* Signed properties of the denomination key.
|
* Signed properties of the denomination key.
|
||||||
*/
|
*/
|
||||||
struct TALER_DenominationKeyValidityPS properties;
|
struct TALER_DenominationKeyValidityPS properties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If denomination was setup for age restriction, non-zero age mask.
|
||||||
|
* Note that the mask is not part of the signature.
|
||||||
|
*/
|
||||||
|
struct TALER_AgeMask age_mask;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -643,7 +649,7 @@ struct TALER_EXCHANGEDB_DenominationKeyMetaData
|
|||||||
* A value of 0 means that the denomination does not support the extension for
|
* A value of 0 means that the denomination does not support the extension for
|
||||||
* age-restriction.
|
* age-restriction.
|
||||||
*/
|
*/
|
||||||
struct TALER_AgeMask age_restrictions;
|
struct TALER_AgeMask age_mask;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -238,6 +238,13 @@ TALER_age_mask_to_string (
|
|||||||
bool
|
bool
|
||||||
TALER_extensions_age_restriction_enabled ();
|
TALER_extensions_age_restriction_enabled ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the currently set age mask
|
||||||
|
*/
|
||||||
|
struct TALER_AgeMask
|
||||||
|
TALER_extensions_age_restriction_ageMask ();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the amount of age groups defined. 0 means no age restriction
|
* Returns the amount of age groups defined. 0 means no age restriction
|
||||||
* enabled.
|
* enabled.
|
||||||
|
@ -67,7 +67,7 @@
|
|||||||
/**
|
/**
|
||||||
* Set to 1 for extra debug logging.
|
* Set to 1 for extra debug logging.
|
||||||
*/
|
*/
|
||||||
#define DEBUG 1 /* FIXME-oec */
|
#define DEBUG 0
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log error related to CURL operations.
|
* Log error related to CURL operations.
|
||||||
@ -667,7 +667,9 @@ decode_keys_json (const json_t *resp_obj,
|
|||||||
enum TALER_EXCHANGE_VersionCompatibility *vc)
|
enum TALER_EXCHANGE_VersionCompatibility *vc)
|
||||||
{
|
{
|
||||||
struct TALER_ExchangeSignatureP sig;
|
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;
|
struct TALER_ExchangePublicKeyP pub;
|
||||||
const char *currency;
|
const char *currency;
|
||||||
struct GNUNET_JSON_Specification mspec[] = {
|
struct GNUNET_JSON_Specification mspec[] = {
|
||||||
@ -746,7 +748,6 @@ decode_keys_json (const json_t *resp_obj,
|
|||||||
key_data->version = GNUNET_strdup (ver);
|
key_data->version = GNUNET_strdup (ver);
|
||||||
}
|
}
|
||||||
|
|
||||||
hash_context = NULL;
|
|
||||||
EXITIF (GNUNET_OK !=
|
EXITIF (GNUNET_OK !=
|
||||||
GNUNET_JSON_parse (resp_obj,
|
GNUNET_JSON_parse (resp_obj,
|
||||||
(check_sig) ? mspec : &mspec[2],
|
(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 */
|
/* parse the master public key and issue date of the response */
|
||||||
if (check_sig)
|
if (check_sig)
|
||||||
|
{
|
||||||
hash_context = GNUNET_CRYPTO_hash_context_start ();
|
hash_context = GNUNET_CRYPTO_hash_context_start ();
|
||||||
|
hash_context_restricted = GNUNET_CRYPTO_hash_context_start ();
|
||||||
|
}
|
||||||
|
|
||||||
/* parse the signing keys */
|
/* parse the signing keys */
|
||||||
{
|
{
|
||||||
@ -829,6 +833,9 @@ decode_keys_json (const json_t *resp_obj,
|
|||||||
EXITIF (GNUNET_OK !=
|
EXITIF (GNUNET_OK !=
|
||||||
TALER_extensions_load_json_config (extensions));
|
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
|
/* parse the denomination keys, merging with the
|
||||||
@ -839,10 +846,15 @@ decode_keys_json (const json_t *resp_obj,
|
|||||||
*/
|
*/
|
||||||
struct
|
struct
|
||||||
{ char *name;
|
{ char *name;
|
||||||
|
struct GNUNET_HashContext *hc;
|
||||||
bool is_optional_age_restriction;}
|
bool is_optional_age_restriction;}
|
||||||
hive[2] = {
|
hive[2] = {
|
||||||
{ "denoms", false },
|
{ "denoms",
|
||||||
{ "age_restricted_denoms", true }
|
hash_context,
|
||||||
|
false },
|
||||||
|
{ "age_restricted_denoms",
|
||||||
|
hash_context_restricted,
|
||||||
|
true }
|
||||||
};
|
};
|
||||||
|
|
||||||
for (size_t s = 0; s < sizeof(hive) / sizeof(hive[0]); s++)
|
for (size_t s = 0; s < sizeof(hive) / sizeof(hive[0]); s++)
|
||||||
@ -873,6 +885,8 @@ decode_keys_json (const json_t *resp_obj,
|
|||||||
struct TALER_EXCHANGE_DenomPublicKey dk;
|
struct TALER_EXCHANGE_DenomPublicKey dk;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
|
have_age_restricted_denom = true;
|
||||||
|
|
||||||
memset (&dk,
|
memset (&dk,
|
||||||
0,
|
0,
|
||||||
sizeof (dk));
|
sizeof (dk));
|
||||||
@ -881,14 +895,15 @@ decode_keys_json (const json_t *resp_obj,
|
|||||||
check_sig,
|
check_sig,
|
||||||
denom_key_obj,
|
denom_key_obj,
|
||||||
&key_data->master_pub,
|
&key_data->master_pub,
|
||||||
hash_context));
|
hive[s].hc));
|
||||||
|
|
||||||
/* Mark age restriction according where we got this denomination from,
|
/* Mark age restriction according where we got this denomination from,
|
||||||
* "denoms" or "age_restricted_denoms" */
|
* "denoms" or "age_restricted_denoms" */
|
||||||
if (hive[s].is_optional_age_restriction)
|
if (hive[s].is_optional_age_restriction)
|
||||||
{
|
{
|
||||||
dk.age_restricted = true;
|
// dk.age_restricted = true;
|
||||||
dk.age_mask.mask = key_data->age_mask.mask;
|
// dk.age_mask.mask = key_data->age_mask.mask;
|
||||||
|
GNUNET_assert (0 != key_data->age_mask.mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int j = 0;
|
for (unsigned int j = 0;
|
||||||
@ -1048,6 +1063,18 @@ decode_keys_json (const json_t *resp_obj,
|
|||||||
.list_issue_date = GNUNET_TIME_timestamp_hton (key_data->list_issue_date)
|
.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,
|
GNUNET_CRYPTO_hash_context_finish (hash_context,
|
||||||
&ks.hc);
|
&ks.hc);
|
||||||
hash_context = NULL;
|
hash_context = NULL;
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
/**
|
/**
|
||||||
* Set to 1 for extra debug logging.
|
* Set to 1 for extra debug logging.
|
||||||
*/
|
*/
|
||||||
#define DEBUG 0
|
#define DEBUG 1 /* FIXME-oec */
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -355,6 +355,7 @@ TALER_EXCHANGE_refresh_prepare (
|
|||||||
struct MeltData md;
|
struct MeltData md;
|
||||||
json_t *ret;
|
json_t *ret;
|
||||||
struct TALER_Amount total;
|
struct TALER_Amount total;
|
||||||
|
struct TALER_AgeCommitmentHash ach = {0};
|
||||||
struct TALER_CoinSpendPublicKeyP coin_pub;
|
struct TALER_CoinSpendPublicKeyP coin_pub;
|
||||||
struct TALER_TransferSecretP trans_sec[TALER_CNC_KAPPA];
|
struct TALER_TransferSecretP trans_sec[TALER_CNC_KAPPA];
|
||||||
struct TALER_RefreshCommitmentEntry rce[TALER_CNC_KAPPA];
|
struct TALER_RefreshCommitmentEntry rce[TALER_CNC_KAPPA];
|
||||||
@ -372,6 +373,7 @@ TALER_EXCHANGE_refresh_prepare (
|
|||||||
md.melted_coin.original_value = melt_pk->value;
|
md.melted_coin.original_value = melt_pk->value;
|
||||||
md.melted_coin.expire_deposit
|
md.melted_coin.expire_deposit
|
||||||
= melt_pk->expire_deposit;
|
= melt_pk->expire_deposit;
|
||||||
|
md.melted_coin.h_age_commitment = ach;
|
||||||
TALER_age_commitment_hash (age_commitment,
|
TALER_age_commitment_hash (age_commitment,
|
||||||
&md.melted_coin.h_age_commitment);
|
&md.melted_coin.h_age_commitment);
|
||||||
|
|
||||||
|
@ -184,6 +184,7 @@ TALER_EXCHANGE_withdraw (
|
|||||||
{
|
{
|
||||||
struct TALER_PlanchetDetail pd;
|
struct TALER_PlanchetDetail pd;
|
||||||
struct TALER_EXCHANGE_WithdrawHandle *wh;
|
struct TALER_EXCHANGE_WithdrawHandle *wh;
|
||||||
|
bool age_restricted = (0 != pk->key.age_mask.mask);
|
||||||
|
|
||||||
wh = GNUNET_new (struct TALER_EXCHANGE_WithdrawHandle);
|
wh = GNUNET_new (struct TALER_EXCHANGE_WithdrawHandle);
|
||||||
wh->exchange = exchange;
|
wh->exchange = exchange;
|
||||||
@ -193,8 +194,8 @@ TALER_EXCHANGE_withdraw (
|
|||||||
wh->ps = *ps;
|
wh->ps = *ps;
|
||||||
wh->ach = ach;
|
wh->ach = ach;
|
||||||
|
|
||||||
GNUNET_assert ( (pk->age_restricted && (NULL != ach)) ||
|
GNUNET_assert ( (age_restricted && (NULL != ach)) ||
|
||||||
(! pk->age_restricted && (NULL == ach)) );
|
(! age_restricted && (NULL == ach)));
|
||||||
|
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
TALER_planchet_prepare (&pk->key,
|
TALER_planchet_prepare (&pk->key,
|
||||||
|
@ -209,6 +209,7 @@ test_exchange_api_LDADD = \
|
|||||||
-lgnunetcurl \
|
-lgnunetcurl \
|
||||||
-lgnunetutil \
|
-lgnunetutil \
|
||||||
-ljansson \
|
-ljansson \
|
||||||
|
-ltalerextensions \
|
||||||
$(XLIB)
|
$(XLIB)
|
||||||
|
|
||||||
test_exchange_management_api_SOURCES = \
|
test_exchange_management_api_SOURCES = \
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include "taler_bank_service.h"
|
#include "taler_bank_service.h"
|
||||||
#include "taler_fakebank_lib.h"
|
#include "taler_fakebank_lib.h"
|
||||||
#include "taler_testing_lib.h"
|
#include "taler_testing_lib.h"
|
||||||
|
#include "taler_extensions.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration file we use. One (big) configuration is used
|
* Configuration file we use. One (big) configuration is used
|
||||||
@ -983,12 +984,12 @@ run (void *cls,
|
|||||||
TALER_TESTING_cmd_auditor_add ("add-auditor-OK",
|
TALER_TESTING_cmd_auditor_add ("add-auditor-OK",
|
||||||
MHD_HTTP_NO_CONTENT,
|
MHD_HTTP_NO_CONTENT,
|
||||||
false),
|
false),
|
||||||
|
TALER_TESTING_cmd_exec_offline_sign_extensions ("offline-sign-extensions",
|
||||||
|
CONFIG_FILE),
|
||||||
TALER_TESTING_cmd_wire_add ("add-wire-account",
|
TALER_TESTING_cmd_wire_add ("add-wire-account",
|
||||||
"payto://x-taler-bank/localhost/2",
|
"payto://x-taler-bank/localhost/2",
|
||||||
MHD_HTTP_NO_CONTENT,
|
MHD_HTTP_NO_CONTENT,
|
||||||
false),
|
false),
|
||||||
TALER_TESTING_cmd_exec_offline_sign_extensions ("offline-sign-extensions",
|
|
||||||
CONFIG_FILE),
|
|
||||||
TALER_TESTING_cmd_exec_offline_sign_keys ("offline-sign-future-keys",
|
TALER_TESTING_cmd_exec_offline_sign_keys ("offline-sign-future-keys",
|
||||||
CONFIG_FILE),
|
CONFIG_FILE),
|
||||||
TALER_TESTING_cmd_exec_offline_sign_fees ("offline-sign-fees",
|
TALER_TESTING_cmd_exec_offline_sign_fees ("offline-sign-fees",
|
||||||
@ -1042,6 +1043,9 @@ main (int argc,
|
|||||||
GNUNET_log_setup ("test-exchange-api",
|
GNUNET_log_setup ("test-exchange-api",
|
||||||
"INFO",
|
"INFO",
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
|
TALER_extensions_init ();
|
||||||
|
|
||||||
/* Check fakebank port is available and get config */
|
/* Check fakebank port is available and get config */
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
TALER_TESTING_prepare_fakebank (CONFIG_FILE,
|
TALER_TESTING_prepare_fakebank (CONFIG_FILE,
|
||||||
|
@ -997,6 +997,7 @@ melt_run (void *cls,
|
|||||||
const struct TALER_DenominationSignature *melt_sig;
|
const struct TALER_DenominationSignature *melt_sig;
|
||||||
const struct TALER_EXCHANGE_DenomPublicKey *melt_denom_pub;
|
const struct TALER_EXCHANGE_DenomPublicKey *melt_denom_pub;
|
||||||
const struct TALER_TESTING_Command *coin_command;
|
const struct TALER_TESTING_Command *coin_command;
|
||||||
|
bool age_restricted;
|
||||||
|
|
||||||
if (NULL == (coin_command
|
if (NULL == (coin_command
|
||||||
= TALER_TESTING_interpreter_lookup_command
|
= TALER_TESTING_interpreter_lookup_command
|
||||||
@ -1026,6 +1027,7 @@ melt_run (void *cls,
|
|||||||
TALER_TESTING_interpreter_fail (rms->is);
|
TALER_TESTING_interpreter_fail (rms->is);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
TALER_TESTING_get_trait_denom_pub (coin_command,
|
TALER_TESTING_get_trait_denom_pub (coin_command,
|
||||||
0,
|
0,
|
||||||
@ -1035,9 +1037,11 @@ melt_run (void *cls,
|
|||||||
TALER_TESTING_interpreter_fail (rms->is);
|
TALER_TESTING_interpreter_fail (rms->is);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Melt amount starts with the melt fee of the old coin; we'll add the
|
/* Melt amount starts with the melt fee of the old coin; we'll add the
|
||||||
values and withdraw fees of the fresh coins next */
|
values and withdraw fees of the fresh coins next */
|
||||||
melt_amount = melt_denom_pub->fee_refresh;
|
melt_amount = melt_denom_pub->fee_refresh;
|
||||||
|
age_restricted = melt_denom_pub->key.age_mask.mask != 0;
|
||||||
for (unsigned int i = 0; i<num_fresh_coins; i++)
|
for (unsigned int i = 0; i<num_fresh_coins; i++)
|
||||||
{
|
{
|
||||||
const struct TALER_EXCHANGE_DenomPublicKey *fresh_pk;
|
const struct TALER_EXCHANGE_DenomPublicKey *fresh_pk;
|
||||||
@ -1055,7 +1059,7 @@ melt_run (void *cls,
|
|||||||
}
|
}
|
||||||
fresh_pk = TALER_TESTING_find_pk (TALER_EXCHANGE_get_keys (is->exchange),
|
fresh_pk = TALER_TESTING_find_pk (TALER_EXCHANGE_get_keys (is->exchange),
|
||||||
&fresh_amount,
|
&fresh_amount,
|
||||||
melt_denom_pub->age_restricted);
|
age_restricted);
|
||||||
if (NULL == fresh_pk)
|
if (NULL == fresh_pk)
|
||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
@ -1080,8 +1084,7 @@ melt_run (void *cls,
|
|||||||
{
|
{
|
||||||
struct TALER_AgeCommitment *ac = NULL;
|
struct TALER_AgeCommitment *ac = NULL;
|
||||||
|
|
||||||
GNUNET_assert (melt_denom_pub->age_restricted ==
|
GNUNET_assert (age_restricted == (NULL != rms->age_commitment));
|
||||||
(NULL != rms->age_commitment));
|
|
||||||
|
|
||||||
if (NULL != rms->age_commitment)
|
if (NULL != rms->age_commitment)
|
||||||
{
|
{
|
||||||
|
@ -464,12 +464,14 @@ withdraw_run (void *cls,
|
|||||||
|
|
||||||
GNUNET_assert (GNUNET_OK ==
|
GNUNET_assert (GNUNET_OK ==
|
||||||
TALER_age_restriction_commit (
|
TALER_age_restriction_commit (
|
||||||
&ws->pk->age_mask,
|
&ws->pk->key.age_mask,
|
||||||
ws->age,
|
ws->age,
|
||||||
seed,
|
seed,
|
||||||
ac));
|
ac));
|
||||||
|
|
||||||
ws->age_commitment = ac;
|
ws->age_commitment = ac;
|
||||||
|
ws->h_age_commitment = GNUNET_malloc (sizeof(struct
|
||||||
|
TALER_AgeCommitmentHash));
|
||||||
TALER_age_commitment_hash (
|
TALER_age_commitment_hash (
|
||||||
ac,
|
ac,
|
||||||
ws->h_age_commitment);
|
ws->h_age_commitment);
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "taler_json_lib.h"
|
#include "taler_json_lib.h"
|
||||||
#include <gnunet/gnunet_curl_lib.h>
|
#include <gnunet/gnunet_curl_lib.h>
|
||||||
#include "taler_signatures.h"
|
#include "taler_signatures.h"
|
||||||
|
#include "taler_extensions.h"
|
||||||
#include "taler_testing_lib.h"
|
#include "taler_testing_lib.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -440,7 +441,7 @@ TALER_TESTING_find_pk (const struct TALER_EXCHANGE_Keys *keys,
|
|||||||
(GNUNET_TIME_timestamp_cmp (now,
|
(GNUNET_TIME_timestamp_cmp (now,
|
||||||
<,
|
<,
|
||||||
pk->withdraw_valid_until)) &&
|
pk->withdraw_valid_until)) &&
|
||||||
(age_restricted == pk->age_restricted) )
|
(age_restricted == (0 != pk->key.age_mask.mask)) )
|
||||||
return pk;
|
return pk;
|
||||||
}
|
}
|
||||||
/* do 2nd pass to check if expiration times are to blame for
|
/* do 2nd pass to check if expiration times are to blame for
|
||||||
@ -457,7 +458,7 @@ TALER_TESTING_find_pk (const struct TALER_EXCHANGE_Keys *keys,
|
|||||||
GNUNET_TIME_timestamp_cmp (now,
|
GNUNET_TIME_timestamp_cmp (now,
|
||||||
>,
|
>,
|
||||||
pk->withdraw_valid_until) ) &&
|
pk->withdraw_valid_until) ) &&
|
||||||
(age_restricted == pk->age_restricted) )
|
(age_restricted == (0 != pk->key.age_mask.mask)) )
|
||||||
{
|
{
|
||||||
GNUNET_log
|
GNUNET_log
|
||||||
(GNUNET_ERROR_TYPE_WARNING,
|
(GNUNET_ERROR_TYPE_WARNING,
|
||||||
|
Loading…
Reference in New Issue
Block a user