[age restriction] progress 11/n
Parse age restriction information from "/keys" - parse "age_restriction" extension, extract mask for age groups - parse denominations from "age_restricted_denoms", too, if available
This commit is contained in:
parent
d91750ca0f
commit
e30989c930
@ -159,6 +159,11 @@ struct TALER_EXCHANGE_DenomPublicKey
|
|||||||
* revoked by the exchange.
|
* revoked by the exchange.
|
||||||
*/
|
*/
|
||||||
bool revoked;
|
bool revoked;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the denomination age-restricted?
|
||||||
|
*/
|
||||||
|
bool age_restricted;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -282,6 +287,11 @@ struct TALER_EXCHANGE_Keys
|
|||||||
*/
|
*/
|
||||||
struct GNUNET_TIME_Timestamp last_denom_issue_date;
|
struct GNUNET_TIME_Timestamp last_denom_issue_date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If age restriction is enabled on the exchange, we get an non-zero age_mask
|
||||||
|
*/
|
||||||
|
struct TALER_AgeMask age_mask;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Length of the @e sign_keys array (number of valid entries).
|
* Length of the @e sign_keys array (number of valid entries).
|
||||||
*/
|
*/
|
||||||
|
@ -110,7 +110,7 @@ TALER_extension_get_by_name (const char *name,
|
|||||||
* @return Error, if age groups were invalid, OK otherwise.
|
* @return Error, if age groups were invalid, OK otherwise.
|
||||||
*/
|
*/
|
||||||
enum TALER_Extension_ReturnValue
|
enum TALER_Extension_ReturnValue
|
||||||
TALER_parse_age_group_string (char *groups,
|
TALER_parse_age_group_string (const char *groups,
|
||||||
struct TALER_AgeMask *mask);
|
struct TALER_AgeMask *mask);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include "taler_exchange_service.h"
|
#include "taler_exchange_service.h"
|
||||||
#include "taler_auditor_service.h"
|
#include "taler_auditor_service.h"
|
||||||
#include "taler_signatures.h"
|
#include "taler_signatures.h"
|
||||||
|
#include "taler_extensions.h"
|
||||||
#include "exchange_api_handle.h"
|
#include "exchange_api_handle.h"
|
||||||
#include "exchange_api_curl_defaults.h"
|
#include "exchange_api_curl_defaults.h"
|
||||||
#include "backoff.h"
|
#include "backoff.h"
|
||||||
@ -345,6 +346,7 @@ parse_json_denomkey (struct TALER_EXCHANGE_DenomPublicKey *denom_key,
|
|||||||
GNUNET_JSON_spec_end ()
|
GNUNET_JSON_spec_end ()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
GNUNET_JSON_parse (denom_key_obj,
|
GNUNET_JSON_parse (denom_key_obj,
|
||||||
spec,
|
spec,
|
||||||
@ -761,6 +763,7 @@ decode_keys_json (const json_t *resp_obj,
|
|||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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 ();
|
||||||
@ -791,63 +794,142 @@ decode_keys_json (const json_t *resp_obj,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Parse the supported extension(s): age-restriction. */
|
||||||
|
/* TODO: maybe lift this into a FP in TALER_Extension ? */
|
||||||
|
{
|
||||||
|
json_t *age_restriction = json_object_get (resp_obj,
|
||||||
|
"age_restriction");
|
||||||
|
|
||||||
|
if (NULL != age_restriction)
|
||||||
|
{
|
||||||
|
bool critical;
|
||||||
|
const char *version;
|
||||||
|
const char *age_groups;
|
||||||
|
struct GNUNET_JSON_Specification spec[] = {
|
||||||
|
GNUNET_JSON_spec_bool ("critical",
|
||||||
|
&critical),
|
||||||
|
GNUNET_JSON_spec_string ("version",
|
||||||
|
&version),
|
||||||
|
GNUNET_JSON_spec_string ("age_groups",
|
||||||
|
&age_groups),
|
||||||
|
GNUNET_JSON_spec_end ()
|
||||||
|
};
|
||||||
|
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_JSON_parse (age_restriction,
|
||||||
|
spec,
|
||||||
|
NULL, NULL))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (critical || // do we care?
|
||||||
|
0 != strncmp (version, "1", 1) ) /* TODO: better compatibility check */
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TALER_Extension_OK !=
|
||||||
|
TALER_parse_age_group_string (age_groups,
|
||||||
|
&key_data->age_mask))
|
||||||
|
{
|
||||||
|
// TODO: print more specific error?
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* parse the denomination keys, merging with the
|
/* parse the denomination keys, merging with the
|
||||||
possibly EXISTING array as required (/keys cherry picking) */
|
possibly EXISTING array as required (/keys cherry picking) */
|
||||||
{
|
{
|
||||||
json_t *denom_keys_array;
|
/* The denominations can be in "denoms" and (optionally) in
|
||||||
json_t *denom_key_obj;
|
* "age_restricted_denoms"
|
||||||
unsigned int index;
|
*/
|
||||||
|
struct
|
||||||
EXITIF (NULL == (denom_keys_array =
|
{ char *name;
|
||||||
json_object_get (resp_obj,
|
bool is_optional_age_restriction;} hive[2] = {
|
||||||
"denoms")));
|
{ "denoms", false },
|
||||||
EXITIF (JSON_ARRAY != json_typeof (denom_keys_array));
|
{ "age_restricted_denoms", true },
|
||||||
|
|
||||||
json_array_foreach (denom_keys_array, index, denom_key_obj) {
|
|
||||||
struct TALER_EXCHANGE_DenomPublicKey dk;
|
|
||||||
bool found = false;
|
|
||||||
|
|
||||||
memset (&dk,
|
|
||||||
0,
|
|
||||||
sizeof (dk));
|
|
||||||
EXITIF (GNUNET_SYSERR ==
|
|
||||||
parse_json_denomkey (&dk,
|
|
||||||
check_sig,
|
|
||||||
denom_key_obj,
|
|
||||||
&key_data->master_pub,
|
|
||||||
hash_context));
|
|
||||||
|
|
||||||
for (unsigned int j = 0;
|
|
||||||
j<key_data->num_denom_keys;
|
|
||||||
j++)
|
|
||||||
{
|
|
||||||
if (0 == denoms_cmp (&dk,
|
|
||||||
&key_data->denom_keys[j]))
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (found)
|
|
||||||
{
|
|
||||||
/* 0:0:0 did not support /keys cherry picking */
|
|
||||||
TALER_LOG_DEBUG ("Skipping denomination key: already know it\n");
|
|
||||||
TALER_denom_pub_free (&dk.key);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (key_data->denom_keys_size == key_data->num_denom_keys)
|
|
||||||
GNUNET_array_grow (key_data->denom_keys,
|
|
||||||
key_data->denom_keys_size,
|
|
||||||
key_data->denom_keys_size * 2 + 2);
|
|
||||||
key_data->denom_keys[key_data->num_denom_keys++] = dk;
|
|
||||||
|
|
||||||
/* Update "last_denom_issue_date" */
|
|
||||||
TALER_LOG_DEBUG ("Adding denomination key that is valid_until %s\n",
|
|
||||||
GNUNET_TIME_timestamp2s (dk.valid_from));
|
|
||||||
key_data->last_denom_issue_date
|
|
||||||
= GNUNET_TIME_timestamp_max (key_data->last_denom_issue_date,
|
|
||||||
dk.valid_from);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
for (size_t s = 0; s < sizeof(hive) / sizeof(hive[0]); s++)
|
||||||
|
{
|
||||||
|
json_t *denom_keys_array;
|
||||||
|
json_t *denom_key_obj;
|
||||||
|
unsigned int index;
|
||||||
|
|
||||||
|
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)
|
||||||
|
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;
|
||||||
|
|
||||||
|
memset (&dk,
|
||||||
|
0,
|
||||||
|
sizeof (dk));
|
||||||
|
EXITIF (GNUNET_SYSERR ==
|
||||||
|
parse_json_denomkey (&dk,
|
||||||
|
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;
|
||||||
|
|
||||||
|
for (unsigned int j = 0;
|
||||||
|
j<key_data->num_denom_keys;
|
||||||
|
j++)
|
||||||
|
{
|
||||||
|
if (0 == denoms_cmp (&dk,
|
||||||
|
&key_data->denom_keys[j]))
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found)
|
||||||
|
{
|
||||||
|
/* 0:0:0 did not support /keys cherry picking */
|
||||||
|
TALER_LOG_DEBUG ("Skipping denomination key: already know it\n");
|
||||||
|
TALER_denom_pub_free (&dk.key);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (key_data->denom_keys_size == key_data->num_denom_keys)
|
||||||
|
GNUNET_array_grow (key_data->denom_keys,
|
||||||
|
key_data->denom_keys_size,
|
||||||
|
key_data->denom_keys_size * 2 + 2);
|
||||||
|
key_data->denom_keys[key_data->num_denom_keys++] = dk;
|
||||||
|
|
||||||
|
/* Update "last_denom_issue_date" */
|
||||||
|
TALER_LOG_DEBUG ("Adding denomination key that is valid_until %s\n",
|
||||||
|
GNUNET_TIME_timestamp2s (dk.valid_from));
|
||||||
|
key_data->last_denom_issue_date
|
||||||
|
= GNUNET_TIME_timestamp_max (key_data->last_denom_issue_date,
|
||||||
|
dk.valid_from);
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* parse the auditor information */
|
/* parse the auditor information */
|
||||||
|
@ -80,7 +80,7 @@ TALER_get_age_mask (const struct GNUNET_CONFIGURATION_Handle *cfg,
|
|||||||
* @return Error if string was invalid, OK otherwise.
|
* @return Error if string was invalid, OK otherwise.
|
||||||
*/
|
*/
|
||||||
enum TALER_Extension_ReturnValue
|
enum TALER_Extension_ReturnValue
|
||||||
TALER_parse_age_group_string (char *groups,
|
TALER_parse_age_group_string (const char *groups,
|
||||||
struct TALER_AgeMask *mask)
|
struct TALER_AgeMask *mask)
|
||||||
{
|
{
|
||||||
enum TALER_Extension_ReturnValue ret = TALER_Extension_ERROR_SYS;
|
enum TALER_Extension_ReturnValue ret = TALER_Extension_ERROR_SYS;
|
||||||
|
Loading…
Reference in New Issue
Block a user