Compare commits
2 Commits
2b85559c06
...
8fe127eb2e
Author | SHA1 | Date | |
---|---|---|---|
8fe127eb2e | |||
ffe4cc06aa |
@ -1 +1 @@
|
|||||||
Subproject commit b0dd85e8187f33a1f92dd5eb31082050d333e168
|
Subproject commit 94b3d826de2aa442a985d03a52eaf526ef950d83
|
@ -285,6 +285,7 @@ check_commitment (struct RevealContext *rctx,
|
|||||||
* @param rctx context for the operation, partially built at this time
|
* @param rctx context for the operation, partially built at this time
|
||||||
* @param link_sigs_json link signatures in JSON format
|
* @param link_sigs_json link signatures in JSON format
|
||||||
* @param new_denoms_h_json requests for fresh coins to be created
|
* @param new_denoms_h_json requests for fresh coins to be created
|
||||||
|
* @param old_age_commitment_json age commitment that went into the withdrawal, maybe NULL
|
||||||
* @param coin_evs envelopes of gamma-selected coins to be signed
|
* @param coin_evs envelopes of gamma-selected coins to be signed
|
||||||
* @return MHD result code
|
* @return MHD result code
|
||||||
*/
|
*/
|
||||||
@ -293,6 +294,7 @@ resolve_refreshes_reveal_denominations (struct MHD_Connection *connection,
|
|||||||
struct RevealContext *rctx,
|
struct RevealContext *rctx,
|
||||||
const json_t *link_sigs_json,
|
const json_t *link_sigs_json,
|
||||||
const json_t *new_denoms_h_json,
|
const json_t *new_denoms_h_json,
|
||||||
|
const json_t *old_age_commitment_json,
|
||||||
const json_t *coin_evs)
|
const json_t *coin_evs)
|
||||||
{
|
{
|
||||||
unsigned int num_fresh_coins = json_array_size (new_denoms_h_json);
|
unsigned int num_fresh_coins = json_array_size (new_denoms_h_json);
|
||||||
@ -317,6 +319,7 @@ resolve_refreshes_reveal_denominations (struct MHD_Connection *connection,
|
|||||||
TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING,
|
TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse denomination key hashes */
|
/* Parse denomination key hashes */
|
||||||
for (unsigned int i = 0; i<num_fresh_coins; i++)
|
for (unsigned int i = 0; i<num_fresh_coins; i++)
|
||||||
{
|
{
|
||||||
@ -443,6 +446,7 @@ resolve_refreshes_reveal_denominations (struct MHD_Connection *connection,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse link signatures array */
|
/* Parse link signatures array */
|
||||||
for (unsigned int i = 0; i<num_fresh_coins; i++)
|
for (unsigned int i = 0; i<num_fresh_coins; i++)
|
||||||
{
|
{
|
||||||
@ -460,6 +464,7 @@ resolve_refreshes_reveal_denominations (struct MHD_Connection *connection,
|
|||||||
-1);
|
-1);
|
||||||
if (GNUNET_OK != res)
|
if (GNUNET_OK != res)
|
||||||
return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
|
return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
|
||||||
|
|
||||||
/* Check signature */
|
/* Check signature */
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
TALER_wallet_link_verify (
|
TALER_wallet_link_verify (
|
||||||
@ -467,6 +472,7 @@ resolve_refreshes_reveal_denominations (struct MHD_Connection *connection,
|
|||||||
&rctx->gamma_tp,
|
&rctx->gamma_tp,
|
||||||
&rrcs[i].coin_envelope_hash,
|
&rrcs[i].coin_envelope_hash,
|
||||||
&rctx->melt.session.coin.coin_pub,
|
&rctx->melt.session.coin.coin_pub,
|
||||||
|
NULL, // TODO-oec: calculate the correct h_age_commitment
|
||||||
&rrcs[i].orig_coin_link_sig))
|
&rrcs[i].orig_coin_link_sig))
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
@ -489,6 +495,7 @@ resolve_refreshes_reveal_denominations (struct MHD_Connection *connection,
|
|||||||
rcd->coin_ev_size = rrc->coin_ev_size;
|
rcd->coin_ev_size = rrc->coin_ev_size;
|
||||||
rcd->dk = &dks[i]->denom_pub;
|
rcd->dk = &dks[i]->denom_pub;
|
||||||
}
|
}
|
||||||
|
|
||||||
rctx->dks = dks;
|
rctx->dks = dks;
|
||||||
rctx->rcds = rcds;
|
rctx->rcds = rcds;
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
@ -500,6 +507,7 @@ resolve_refreshes_reveal_denominations (struct MHD_Connection *connection,
|
|||||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||||
"Creating %u signatures\n",
|
"Creating %u signatures\n",
|
||||||
(unsigned int) rctx->num_fresh_coins);
|
(unsigned int) rctx->num_fresh_coins);
|
||||||
|
|
||||||
/* create fresh coin signatures */
|
/* create fresh coin signatures */
|
||||||
for (unsigned int i = 0; i<rctx->num_fresh_coins; i++)
|
for (unsigned int i = 0; i<rctx->num_fresh_coins; i++)
|
||||||
{
|
{
|
||||||
@ -520,8 +528,10 @@ resolve_refreshes_reveal_denominations (struct MHD_Connection *connection,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||||
"Signatures ready, starting DB interaction\n");
|
"Signatures ready, starting DB interaction\n");
|
||||||
|
|
||||||
/* Persist operation result in DB */
|
/* Persist operation result in DB */
|
||||||
{
|
{
|
||||||
enum GNUNET_DB_QueryStatus qs;
|
enum GNUNET_DB_QueryStatus qs;
|
||||||
@ -577,11 +587,18 @@ cleanup:
|
|||||||
* revealed information is valid then returns the signed refreshed
|
* revealed information is valid then returns the signed refreshed
|
||||||
* coins.
|
* coins.
|
||||||
*
|
*
|
||||||
|
* If the denomination has age restriction support, the array of EDDSA public
|
||||||
|
* keys, one for each age group that was activated during the withdrawal
|
||||||
|
* by the parent/ward, must be provided in old_age_commitment. The hash of
|
||||||
|
* this array must be the same as the h_age_commitment of the persisted reveal
|
||||||
|
* request.
|
||||||
|
*
|
||||||
* @param connection the MHD connection to handle
|
* @param connection the MHD connection to handle
|
||||||
* @param rctx context for the operation, partially built at this time
|
* @param rctx context for the operation, partially built at this time
|
||||||
* @param tp_json private transfer keys in JSON format
|
* @param tp_json private transfer keys in JSON format
|
||||||
* @param link_sigs_json link signatures in JSON format
|
* @param link_sigs_json link signatures in JSON format
|
||||||
* @param new_denoms_h_json requests for fresh coins to be created
|
* @param new_denoms_h_json requests for fresh coins to be created
|
||||||
|
* @param old_age_commitment_json array of EDDSA public keys in JSON, used for age restriction, maybe NULL
|
||||||
* @param coin_evs envelopes of gamma-selected coins to be signed
|
* @param coin_evs envelopes of gamma-selected coins to be signed
|
||||||
* @return MHD result code
|
* @return MHD result code
|
||||||
*/
|
*/
|
||||||
@ -591,6 +608,7 @@ handle_refreshes_reveal_json (struct MHD_Connection *connection,
|
|||||||
const json_t *tp_json,
|
const json_t *tp_json,
|
||||||
const json_t *link_sigs_json,
|
const json_t *link_sigs_json,
|
||||||
const json_t *new_denoms_h_json,
|
const json_t *new_denoms_h_json,
|
||||||
|
const json_t *old_age_commitment_json,
|
||||||
const json_t *coin_evs)
|
const json_t *coin_evs)
|
||||||
{
|
{
|
||||||
unsigned int num_fresh_coins = json_array_size (new_denoms_h_json);
|
unsigned int num_fresh_coins = json_array_size (new_denoms_h_json);
|
||||||
@ -626,6 +644,19 @@ handle_refreshes_reveal_json (struct MHD_Connection *connection,
|
|||||||
"new_denoms/link_sigs");
|
"new_denoms/link_sigs");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Sanity check of age commitment: If it was provided, it _must_ be an array
|
||||||
|
* of the size the # of age groups */
|
||||||
|
if (NULL != old_age_commitment_json
|
||||||
|
&& TALER_extensions_age_restriction_num_groups () !=
|
||||||
|
json_array_size (old_age_commitment_json))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
return TALER_MHD_reply_with_error (connection,
|
||||||
|
MHD_HTTP_BAD_REQUEST,
|
||||||
|
TALER_EC_EXCHANGE_REFRESHES_REVEAL_AGE_RESTRICTION_COMMITMENT_INVALID,
|
||||||
|
"old_age_commitment");
|
||||||
|
}
|
||||||
|
|
||||||
/* Parse transfer private keys array */
|
/* Parse transfer private keys array */
|
||||||
for (unsigned int i = 0; i<num_tprivs; i++)
|
for (unsigned int i = 0; i<num_tprivs; i++)
|
||||||
{
|
{
|
||||||
@ -649,6 +680,7 @@ handle_refreshes_reveal_json (struct MHD_Connection *connection,
|
|||||||
rctx,
|
rctx,
|
||||||
link_sigs_json,
|
link_sigs_json,
|
||||||
new_denoms_h_json,
|
new_denoms_h_json,
|
||||||
|
old_age_commitment_json,
|
||||||
coin_evs);
|
coin_evs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -662,6 +694,7 @@ TEH_handler_reveal (struct TEH_RequestContext *rc,
|
|||||||
json_t *transfer_privs;
|
json_t *transfer_privs;
|
||||||
json_t *link_sigs;
|
json_t *link_sigs;
|
||||||
json_t *new_denoms_h;
|
json_t *new_denoms_h;
|
||||||
|
json_t *old_age_commitment = NULL;
|
||||||
struct RevealContext rctx;
|
struct RevealContext rctx;
|
||||||
struct GNUNET_JSON_Specification spec[] = {
|
struct GNUNET_JSON_Specification spec[] = {
|
||||||
GNUNET_JSON_spec_fixed_auto ("transfer_pub",
|
GNUNET_JSON_spec_fixed_auto ("transfer_pub",
|
||||||
@ -674,6 +707,9 @@ TEH_handler_reveal (struct TEH_RequestContext *rc,
|
|||||||
&coin_evs),
|
&coin_evs),
|
||||||
GNUNET_JSON_spec_json ("new_denoms_h",
|
GNUNET_JSON_spec_json ("new_denoms_h",
|
||||||
&new_denoms_h),
|
&new_denoms_h),
|
||||||
|
GNUNET_JSON_spec_mark_optional (
|
||||||
|
GNUNET_JSON_spec_json ("old_age_commitment",
|
||||||
|
&old_age_commitment)),
|
||||||
GNUNET_JSON_spec_end ()
|
GNUNET_JSON_spec_end ()
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -735,6 +771,7 @@ TEH_handler_reveal (struct TEH_RequestContext *rc,
|
|||||||
transfer_privs,
|
transfer_privs,
|
||||||
link_sigs,
|
link_sigs,
|
||||||
new_denoms_h,
|
new_denoms_h,
|
||||||
|
old_age_commitment,
|
||||||
coin_evs);
|
coin_evs);
|
||||||
GNUNET_JSON_parse_free (spec);
|
GNUNET_JSON_parse_free (spec);
|
||||||
return res;
|
return res;
|
||||||
|
@ -830,6 +830,7 @@ prepare_statements (struct PostgresClosure *pg)
|
|||||||
",denoms.fee_refresh_frac"
|
",denoms.fee_refresh_frac"
|
||||||
",old_coin_pub"
|
",old_coin_pub"
|
||||||
",old_coin_sig"
|
",old_coin_sig"
|
||||||
|
",h_age_commitment"
|
||||||
",amount_with_fee_val"
|
",amount_with_fee_val"
|
||||||
",amount_with_fee_frac"
|
",amount_with_fee_frac"
|
||||||
",noreveal_index"
|
",noreveal_index"
|
||||||
@ -6020,6 +6021,7 @@ postgres_get_melt (void *cls,
|
|||||||
uint64_t *melt_serial_id)
|
uint64_t *melt_serial_id)
|
||||||
{
|
{
|
||||||
struct PostgresClosure *pg = cls;
|
struct PostgresClosure *pg = cls;
|
||||||
|
bool h_age_commitment_is_null;
|
||||||
struct GNUNET_PQ_QueryParam params[] = {
|
struct GNUNET_PQ_QueryParam params[] = {
|
||||||
GNUNET_PQ_query_param_auto_from_type (rc),
|
GNUNET_PQ_query_param_auto_from_type (rc),
|
||||||
GNUNET_PQ_query_param_end
|
GNUNET_PQ_query_param_end
|
||||||
@ -6036,6 +6038,10 @@ postgres_get_melt (void *cls,
|
|||||||
&melt->session.coin.coin_pub),
|
&melt->session.coin.coin_pub),
|
||||||
GNUNET_PQ_result_spec_auto_from_type ("old_coin_sig",
|
GNUNET_PQ_result_spec_auto_from_type ("old_coin_sig",
|
||||||
&melt->session.coin_sig),
|
&melt->session.coin_sig),
|
||||||
|
GNUNET_PQ_result_spec_allow_null (
|
||||||
|
GNUNET_PQ_result_spec_auto_from_type ("h_age_commitment",
|
||||||
|
&melt->session.h_age_commitment),
|
||||||
|
&h_age_commitment_is_null),
|
||||||
TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
|
TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
|
||||||
&melt->session.amount_with_fee),
|
&melt->session.amount_with_fee),
|
||||||
GNUNET_PQ_result_spec_uint64 ("melt_serial_id",
|
GNUNET_PQ_result_spec_uint64 ("melt_serial_id",
|
||||||
@ -6051,6 +6057,11 @@ postgres_get_melt (void *cls,
|
|||||||
"get_melt",
|
"get_melt",
|
||||||
params,
|
params,
|
||||||
rs);
|
rs);
|
||||||
|
if (h_age_commitment_is_null)
|
||||||
|
memset (&melt->session.h_age_commitment,
|
||||||
|
0,
|
||||||
|
sizeof(melt->session.h_age_commitment));
|
||||||
|
|
||||||
melt->session.rc = *rc;
|
melt->session.rc = *rc;
|
||||||
return qs;
|
return qs;
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,19 @@
|
|||||||
#include "taler_extensions.h"
|
#include "taler_extensions.h"
|
||||||
#include "stdint.h"
|
#include "stdint.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Carries all the information we need for age restriction
|
||||||
|
*/
|
||||||
|
struct age_restriction_config
|
||||||
|
{
|
||||||
|
struct TALER_AgeMask mask;
|
||||||
|
size_t num_groups;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Global config for this extension
|
||||||
|
*/
|
||||||
|
static struct age_restriction_config _config = {0};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param groups String representation of the age groups. Must be of the form
|
* @param groups String representation of the age groups. Must be of the form
|
||||||
@ -146,6 +159,9 @@ age_restriction_disable (
|
|||||||
json_decref (this->config_json);
|
json_decref (this->config_json);
|
||||||
this->config_json = NULL;
|
this->config_json = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_config.mask.mask = 0;
|
||||||
|
_config.num_groups = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -197,7 +213,6 @@ age_restriction_load_taler_config (
|
|||||||
|
|
||||||
|
|
||||||
mask.mask = TALER_EXTENSION_AGE_RESTRICTION_DEFAULT_AGE_MASK;
|
mask.mask = TALER_EXTENSION_AGE_RESTRICTION_DEFAULT_AGE_MASK;
|
||||||
|
|
||||||
ret = GNUNET_OK;
|
ret = GNUNET_OK;
|
||||||
|
|
||||||
if (groups != NULL)
|
if (groups != NULL)
|
||||||
@ -208,7 +223,11 @@ age_restriction_load_taler_config (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (GNUNET_OK == ret)
|
if (GNUNET_OK == ret)
|
||||||
this->config = (void *) (size_t) mask.mask;
|
{
|
||||||
|
_config.mask.mask = mask.mask;
|
||||||
|
_config.num_groups = __builtin_popcount (mask.mask);
|
||||||
|
this->config = &_config;
|
||||||
|
}
|
||||||
|
|
||||||
GNUNET_free (groups);
|
GNUNET_free (groups);
|
||||||
return ret;
|
return ret;
|
||||||
@ -223,12 +242,12 @@ age_restriction_load_taler_config (
|
|||||||
static enum GNUNET_GenericReturnValue
|
static enum GNUNET_GenericReturnValue
|
||||||
age_restriction_load_json_config (
|
age_restriction_load_json_config (
|
||||||
struct TALER_Extension *this,
|
struct TALER_Extension *this,
|
||||||
json_t *config)
|
json_t *jconfig)
|
||||||
{
|
{
|
||||||
struct TALER_AgeMask mask = {0};
|
struct TALER_AgeMask mask = {0};
|
||||||
enum GNUNET_GenericReturnValue ret;
|
enum GNUNET_GenericReturnValue ret;
|
||||||
|
|
||||||
ret = TALER_JSON_parse_agemask (config, &mask);
|
ret = TALER_JSON_parse_agemask (jconfig, &mask);
|
||||||
if (GNUNET_OK != ret)
|
if (GNUNET_OK != ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -239,16 +258,15 @@ age_restriction_load_json_config (
|
|||||||
if (TALER_Extension_AgeRestriction != this->type)
|
if (TALER_Extension_AgeRestriction != this->type)
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
|
|
||||||
if (NULL != this->config)
|
|
||||||
GNUNET_free (this->config);
|
|
||||||
|
|
||||||
this->config = GNUNET_malloc (sizeof(struct TALER_AgeMask));
|
_config.mask.mask = mask.mask;
|
||||||
GNUNET_memcpy (this->config, &mask, sizeof(struct TALER_AgeMask));
|
_config.num_groups = __builtin_popcount (mask.mask);
|
||||||
|
this->config = &_config;
|
||||||
|
|
||||||
if (NULL != this->config_json)
|
if (NULL != this->config_json)
|
||||||
json_decref (this->config_json);
|
json_decref (this->config_json);
|
||||||
|
|
||||||
this->config_json = config;
|
this->config_json = jconfig;
|
||||||
|
|
||||||
return GNUNET_OK;
|
return GNUNET_OK;
|
||||||
}
|
}
|
||||||
@ -263,7 +281,6 @@ json_t *
|
|||||||
age_restriction_config_to_json (
|
age_restriction_config_to_json (
|
||||||
const struct TALER_Extension *this)
|
const struct TALER_Extension *this)
|
||||||
{
|
{
|
||||||
struct TALER_AgeMask mask;
|
|
||||||
char *mask_str;
|
char *mask_str;
|
||||||
json_t *conf;
|
json_t *conf;
|
||||||
|
|
||||||
@ -275,8 +292,7 @@ age_restriction_config_to_json (
|
|||||||
return json_copy (this->config_json);
|
return json_copy (this->config_json);
|
||||||
}
|
}
|
||||||
|
|
||||||
mask.mask = (uint32_t) (size_t) this->config;
|
mask_str = TALER_age_mask_to_string (&_config.mask);
|
||||||
mask_str = TALER_age_mask_to_string (&mask);
|
|
||||||
conf = GNUNET_JSON_PACK (
|
conf = GNUNET_JSON_PACK (
|
||||||
GNUNET_JSON_pack_string ("age_groups", mask_str)
|
GNUNET_JSON_pack_string ("age_groups", mask_str)
|
||||||
);
|
);
|
||||||
@ -318,4 +334,18 @@ struct TALER_Extension _extension_age_restriction = {
|
|||||||
.load_taler_config = &age_restriction_load_taler_config,
|
.load_taler_config = &age_restriction_load_taler_config,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool
|
||||||
|
TALER_extensions_age_restriction_enabled ()
|
||||||
|
{
|
||||||
|
return (0 != _config.mask.mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t
|
||||||
|
TALER_extensions_age_restriction_num_groups ()
|
||||||
|
{
|
||||||
|
return _config.num_groups;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* end of extension_age_restriction.c */
|
/* end of extension_age_restriction.c */
|
||||||
|
@ -311,9 +311,11 @@ struct TALER_AgeHash
|
|||||||
struct GNUNET_ShortHashCode shash;
|
struct GNUNET_ShortHashCode shash;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool
|
extern const struct TALER_AgeHash TALER_AgeHash_zeroHash;
|
||||||
TALER_AgeHash_isZero (
|
#define TALER_AgeHash_isZero(ph) ((NULL == ph) || \
|
||||||
const struct TALER_AgeHash *hash);
|
(0 == memcmp (ph, \
|
||||||
|
&TALER_AgeHash_zeroHash, \
|
||||||
|
sizeof(struct TALER_AgeHash))))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Type of public keys for Taler coins. The same key material is used
|
* @brief Type of public keys for Taler coins. The same key material is used
|
||||||
@ -1809,6 +1811,7 @@ TALER_wallet_link_sign (const struct TALER_DenominationHash *h_denom_pub,
|
|||||||
* @param transfer_pub transfer public key
|
* @param transfer_pub transfer public key
|
||||||
* @param h_coin_ev hash of the coin envelope
|
* @param h_coin_ev hash of the coin envelope
|
||||||
* @param old_coin_pub old coin key that the link signature is for
|
* @param old_coin_pub old coin key that the link signature is for
|
||||||
|
* @param h_age_commitment hash of age commitment. Maybe NULL, if not applicable.
|
||||||
* @param coin_sig resulting signature
|
* @param coin_sig resulting signature
|
||||||
* @return #GNUNET_OK if the signature is valid
|
* @return #GNUNET_OK if the signature is valid
|
||||||
*/
|
*/
|
||||||
@ -1818,6 +1821,7 @@ TALER_wallet_link_verify (
|
|||||||
const struct TALER_TransferPublicKeyP *transfer_pub,
|
const struct TALER_TransferPublicKeyP *transfer_pub,
|
||||||
const struct TALER_BlindedCoinHash *h_coin_ev,
|
const struct TALER_BlindedCoinHash *h_coin_ev,
|
||||||
const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
|
const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
|
||||||
|
const struct TALER_AgeHash *h_age_commitment,
|
||||||
const struct TALER_CoinSpendSignatureP *coin_sig);
|
const struct TALER_CoinSpendSignatureP *coin_sig);
|
||||||
|
|
||||||
|
|
||||||
|
@ -1260,6 +1260,13 @@ struct TALER_EXCHANGEDB_Refresh
|
|||||||
*/
|
*/
|
||||||
struct TALER_CoinSpendSignatureP coin_sig;
|
struct TALER_CoinSpendSignatureP coin_sig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hash of the age commitment used to sign the coin, if age restriction was
|
||||||
|
* applicable to the denomination. May be all zeroes if no age restriction
|
||||||
|
* applies.
|
||||||
|
*/
|
||||||
|
struct TALER_AgeHash h_age_commitment;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Refresh commitment this coin is melted into.
|
* Refresh commitment this coin is melted into.
|
||||||
*/
|
*/
|
||||||
@ -1306,8 +1313,9 @@ struct TALER_EXCHANGEDB_MeltListEntry
|
|||||||
struct TALER_DenominationHash h_denom_pub;
|
struct TALER_DenominationHash h_denom_pub;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hash of the age commitment used to sign the coin. May be all zeroes if no
|
* Hash of the age commitment used to sign the coin, if age restriction was
|
||||||
* age restriction applies.
|
* applicable to the denomination. May be all zeroes if no age restriction
|
||||||
|
* applies.
|
||||||
*/
|
*/
|
||||||
struct TALER_AgeHash h_age_commitment;
|
struct TALER_AgeHash h_age_commitment;
|
||||||
|
|
||||||
|
@ -221,6 +221,18 @@ char *
|
|||||||
TALER_age_mask_to_string (
|
TALER_age_mask_to_string (
|
||||||
const struct TALER_AgeMask *mask);
|
const struct TALER_AgeMask *mask);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true when age restriction is enabled
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
TALER_extensions_age_restriction_enabled ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the amount of age groups defined. 0 means no age restriction
|
||||||
|
* enabled.
|
||||||
|
*/
|
||||||
|
size_t
|
||||||
|
TALER_extensions_age_restriction_num_groups ();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO: Add Peer2Peer Extension
|
* TODO: Add Peer2Peer Extension
|
||||||
|
@ -414,6 +414,11 @@ struct TALER_LinkDataPS
|
|||||||
*/
|
*/
|
||||||
struct TALER_TransferPublicKeyP transfer_pub;
|
struct TALER_TransferPublicKeyP transfer_pub;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hash of the age commitment, if applicable. Can be all zero
|
||||||
|
*/
|
||||||
|
struct TALER_AgeHash h_age_commitment;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hash of the blinded new coin.
|
* Hash of the blinded new coin.
|
||||||
*/
|
*/
|
||||||
|
@ -105,6 +105,7 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh,
|
|||||||
};
|
};
|
||||||
struct TALER_TransferSecretP secret;
|
struct TALER_TransferSecretP secret;
|
||||||
struct TALER_PlanchetSecretsP fc;
|
struct TALER_PlanchetSecretsP fc;
|
||||||
|
struct TALER_AgeHash h_age_commitment = {0}; // TODO, see below.
|
||||||
|
|
||||||
/* parse reply */
|
/* parse reply */
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
@ -156,11 +157,21 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh,
|
|||||||
pd.coin_ev_size,
|
pd.coin_ev_size,
|
||||||
&coin_envelope_hash.hash);
|
&coin_envelope_hash.hash);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO-oec: Derive the age commitment vector and hash it into
|
||||||
|
* h_age_commitment.
|
||||||
|
* Questions:
|
||||||
|
* - Where do we get the information about the support for age
|
||||||
|
* restriction of the denomination?
|
||||||
|
* - Where do we get the information bout the previous coin's age groups?
|
||||||
|
*/
|
||||||
|
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
TALER_wallet_link_verify (&pd.denom_pub_hash,
|
TALER_wallet_link_verify (&pd.denom_pub_hash,
|
||||||
trans_pub,
|
trans_pub,
|
||||||
&coin_envelope_hash,
|
&coin_envelope_hash,
|
||||||
&old_coin_pub,
|
&old_coin_pub,
|
||||||
|
&h_age_commitment,
|
||||||
&link_sig))
|
&link_sig))
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
|
@ -25,6 +25,10 @@
|
|||||||
#include "taler_util.h"
|
#include "taler_util.h"
|
||||||
#include <gcrypt.h>
|
#include <gcrypt.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used in TALER_AgeHash_isZero for comparison
|
||||||
|
*/
|
||||||
|
const struct TALER_AgeHash TALER_AgeHash_zeroHash = {0};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function called by libgcrypt on serious errors.
|
* Function called by libgcrypt on serious errors.
|
||||||
@ -352,13 +356,4 @@ TALER_coin_pub_hash (const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
TALER_AgeHash_isZero (
|
|
||||||
const struct TALER_AgeHash *hash)
|
|
||||||
{
|
|
||||||
static struct TALER_AgeHash zeroAgeHash = {0};
|
|
||||||
return (0 == memcmp (hash, &zeroAgeHash, sizeof(struct TALER_AgeHash)));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* end of crypto.c */
|
/* end of crypto.c */
|
||||||
|
@ -135,6 +135,7 @@ TALER_wallet_link_verify (
|
|||||||
const struct TALER_TransferPublicKeyP *transfer_pub,
|
const struct TALER_TransferPublicKeyP *transfer_pub,
|
||||||
const struct TALER_BlindedCoinHash *h_coin_ev,
|
const struct TALER_BlindedCoinHash *h_coin_ev,
|
||||||
const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
|
const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
|
||||||
|
const struct TALER_AgeHash *h_age_commitment,
|
||||||
const struct TALER_CoinSpendSignatureP *coin_sig)
|
const struct TALER_CoinSpendSignatureP *coin_sig)
|
||||||
{
|
{
|
||||||
struct TALER_LinkDataPS ldp = {
|
struct TALER_LinkDataPS ldp = {
|
||||||
@ -145,6 +146,13 @@ TALER_wallet_link_verify (
|
|||||||
.coin_envelope_hash = *h_coin_ev
|
.coin_envelope_hash = *h_coin_ev
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (NULL == h_age_commitment)
|
||||||
|
memset (&ldp.h_age_commitment,
|
||||||
|
0,
|
||||||
|
sizeof(*h_age_commitment));
|
||||||
|
else
|
||||||
|
ldp.h_age_commitment = *h_age_commitment;
|
||||||
|
|
||||||
return
|
return
|
||||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_LINK,
|
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_LINK,
|
||||||
&ldp,
|
&ldp,
|
||||||
|
Loading…
Reference in New Issue
Block a user