fix memory leaks reported by valgrind

This commit is contained in:
Özgür Kesim 2023-07-10 10:23:52 +02:00
parent 9d706a01a2
commit 3024dc9fa5
Signed by: oec
GPG Key ID: 3D76A56D79EDD9D7
17 changed files with 269 additions and 176 deletions

View File

@ -184,7 +184,7 @@ configure_extension (
{ {
struct LoadConfClosure *col = cls; struct LoadConfClosure *col = cls;
const char *name; const char *name;
char *lib_name; char lib_name[1024] = {0};
struct TALER_Extension *extension; struct TALER_Extension *extension;
if (GNUNET_OK != col->error) if (GNUNET_OK != col->error)
@ -199,17 +199,16 @@ configure_extension (
/* Load the extension library */ /* Load the extension library */
GNUNET_asprintf (&lib_name, GNUNET_snprintf (lib_name,
sizeof(lib_name),
"libtaler_extension_%s", "libtaler_extension_%s",
name); name);
/* Lower-case extension name, config is case-insensitive */ /* Lower-case extension name, config is case-insensitive */
for (unsigned int i = 0; i < strlen (lib_name); i++) for (unsigned int i = 0; i < strlen (lib_name); i++)
{
lib_name[i] = tolower (lib_name[i]); lib_name[i] = tolower (lib_name[i]);
}
extension = GNUNET_PLUGIN_load ( extension = GNUNET_PLUGIN_load (lib_name,
lib_name, (void *) col->cfg);
(void *) col->cfg);
if (NULL == extension) if (NULL == extension)
{ {
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,

View File

@ -5947,33 +5947,54 @@ TALER_age_commitment_verify (
/** /**
* @brief helper function to free memory of a struct TALER_AgeCommitment * @brief helper function to free memory of a struct TALER_AgeCommitment
* *
* @param p the commitment from which all memory should be freed. * @param ac the commitment from which all memory should be freed.
*/ */
void void
TALER_age_commitment_free ( TALER_age_commitment_free (
struct TALER_AgeCommitment *p); struct TALER_AgeCommitment *ac);
/** /**
* @brief helper function to free memory of a struct TALER_AgeProof * @brief helper function to free memory of a struct TALER_AgeProof
* *
* @param p the proof of commitment from which all memory should be freed. * @param ap the proof of commitment from which all memory should be freed.
*/ */
void void
TALER_age_proof_free ( TALER_age_proof_free (
struct TALER_AgeProof *p); struct TALER_AgeProof *ap);
/** /**
* @brief helper function to free memory of a struct TALER_AgeCommitmentProof * @brief helper function to free memory of a struct TALER_AgeCommitmentProof
* *
* @param p the commitment and its proof from which all memory should be freed. * @param acp the commitment and its proof from which all memory should be freed.
*/ */
void void
TALER_age_commitment_proof_free ( TALER_age_commitment_proof_free (
struct TALER_AgeCommitmentProof *p); struct TALER_AgeCommitmentProof *acp);
/**
* @brief helper function to allocate and copy a struct TALER_AgeCommitmentProof
*
* @param[in] acp The original age commitment proof
* @return The deep copy of @e acp, allocated
*/
struct TALER_AgeCommitmentProof *
TALER_age_commitment_proof_duplicate (
const struct TALER_AgeCommitmentProof *acp);
/**
* @brief helper function to copy a struct TALER_AgeCommitmentProof
*
* @param[in] acp The original age commitment proof
* @param[out] nacp The struct to copy the data into, with freshly allocated and copied keys.
*/
void
TALER_age_commitment_proof_deep_copy (
const struct TALER_AgeCommitmentProof *acp,
struct TALER_AgeCommitmentProof *nacp);
/** /**
* @brief For age-withdraw, clients have to prove that the public keys for all * @brief For age-withdraw, clients have to prove that the public keys for all
* age groups larger than the allowed maximum age group are derived by scalar * age groups larger than the allowed maximum age group are derived by scalar

View File

@ -3043,7 +3043,7 @@ struct TALER_EXCHANGE_RevealedCoinInfo
* Age commitment and its hash of the coin, might be NULL. * Age commitment and its hash of the coin, might be NULL.
*/ */
struct TALER_AgeCommitmentProof *age_commitment_proof; struct TALER_AgeCommitmentProof *age_commitment_proof;
struct TALER_AgeCommitmentHash *h_age_commitment; struct TALER_AgeCommitmentHash h_age_commitment;
/** /**
* Blinding keys used to blind the fresh coin. * Blinding keys used to blind the fresh coin.
@ -3187,10 +3187,11 @@ struct TALER_EXCHANGE_LinkedCoinInfo
struct TALER_CoinSpendPrivateKeyP coin_priv; struct TALER_CoinSpendPrivateKeyP coin_priv;
/** /**
* Age commitment and its hash, if applicable. Might be NULL. * Age commitment and its hash, if applicable.
*/ */
struct TALER_AgeCommitmentProof *age_commitment_proof; bool has_age_commitment;
struct TALER_AgeCommitmentHash *h_age_commitment; struct TALER_AgeCommitmentProof age_commitment_proof;
struct TALER_AgeCommitmentHash h_age_commitment;
/** /**
* Master secret of this coin. * Master secret of this coin.

View File

@ -578,11 +578,14 @@ TALER_parse_age_group_string (
/** /**
* @brief Encodes the age mask into a string, like "8:10:12:14:16:18:21" * @brief Encodes the age mask into a string, like "8:10:12:14:16:18:21"
* *
* NOTE: This function uses a static buffer. It is not safe to call this
* function concurrently.
*
* @param mask Age mask * @param mask Age mask
* @return String representation of the age mask, allocated by GNUNET_malloc. * @return String representation of the age mask.
* Can be used as value in the TALER config. * Can be used as value in the TALER config.
*/ */
char * const char *
TALER_age_mask_to_string ( TALER_age_mask_to_string (
const struct TALER_AgeMask *mask); const struct TALER_AgeMask *mask);

View File

@ -114,6 +114,7 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh,
struct TALER_TransferSecretP secret; struct TALER_TransferSecretP secret;
struct TALER_PlanchetDetail pd; struct TALER_PlanchetDetail pd;
struct TALER_CoinPubHashP c_hash; struct TALER_CoinPubHashP c_hash;
struct TALER_AgeCommitmentHash *pach = NULL;
/* parse reply */ /* parse reply */
if (GNUNET_OK != if (GNUNET_OK !=
@ -137,34 +138,35 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh,
&alg_values, &alg_values,
&bks); &bks);
lci->age_commitment_proof = NULL; lci->has_age_commitment = false;
lci->h_age_commitment = NULL;
/* Derive the age commitment and calculate the hash */ /* Derive the age commitment and calculate the hash */
if (NULL != lh->age_commitment_proof) if (NULL != lh->age_commitment_proof)
{ {
lci->age_commitment_proof = GNUNET_new (struct TALER_AgeCommitmentProof);
lci->h_age_commitment = GNUNET_new (struct TALER_AgeCommitmentHash);
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_age_commitment_derive ( TALER_age_commitment_derive (
lh->age_commitment_proof, lh->age_commitment_proof,
&secret.key, &secret.key,
lci->age_commitment_proof)); &lci->age_commitment_proof));
TALER_age_commitment_hash ( TALER_age_commitment_hash (
&(lci->age_commitment_proof->commitment), &lci->age_commitment_proof.commitment,
lci->h_age_commitment); &lci->h_age_commitment);
lci->has_age_commitment = true;
pach = &lci->h_age_commitment;
} }
if (GNUNET_OK != if (GNUNET_OK !=
TALER_planchet_prepare (&rpub, TALER_planchet_prepare (
&alg_values, &rpub,
&bks, &alg_values,
&lci->coin_priv, &bks,
lci->h_age_commitment, &lci->coin_priv,
&c_hash, pach,
&pd)) &c_hash,
&pd))
{ {
GNUNET_break (0); GNUNET_break (0);
GNUNET_JSON_parse_free (spec); GNUNET_JSON_parse_free (spec);
@ -364,6 +366,8 @@ parse_link_ok (struct TALER_EXCHANGE_LinkHandle *lh,
{ {
TALER_denom_sig_free (&lcis[i].sig); TALER_denom_sig_free (&lcis[i].sig);
TALER_denom_pub_free (&lcis[i].pub); TALER_denom_pub_free (&lcis[i].pub);
if (lcis[i].has_age_commitment)
TALER_age_commitment_proof_free (&lcis[i].age_commitment_proof);
} }
} }
return ret; return ret;
@ -513,6 +517,7 @@ TALER_EXCHANGE_link_cancel (struct TALER_EXCHANGE_LinkHandle *lh)
GNUNET_CURL_job_cancel (lh->job); GNUNET_CURL_job_cancel (lh->job);
lh->job = NULL; lh->job = NULL;
} }
GNUNET_free (lh->url); GNUNET_free (lh->url);
GNUNET_free (lh); GNUNET_free (lh);
} }

View File

@ -336,13 +336,14 @@ start_melt (struct TALER_EXCHANGE_MeltHandle *mh)
} }
TALER_denom_pub_hash (&mh->md.melted_coin.pub_key, TALER_denom_pub_hash (&mh->md.melted_coin.pub_key,
&h_denom_pub); &h_denom_pub);
TALER_wallet_melt_sign (&mh->md.melted_coin.melt_amount_with_fee, TALER_wallet_melt_sign (
&mh->md.melted_coin.fee_melt, &mh->md.melted_coin.melt_amount_with_fee,
&mh->md.rc, &mh->md.melted_coin.fee_melt,
&h_denom_pub, &mh->md.rc,
mh->md.melted_coin.h_age_commitment, &h_denom_pub,
&mh->md.melted_coin.coin_priv, mh->md.melted_coin.h_age_commitment,
&mh->coin_sig); &mh->md.melted_coin.coin_priv,
&mh->coin_sig);
GNUNET_CRYPTO_eddsa_key_get_public (&mh->md.melted_coin.coin_priv.eddsa_priv, GNUNET_CRYPTO_eddsa_key_get_public (&mh->md.melted_coin.coin_priv.eddsa_priv,
&mh->coin_pub.eddsa_pub); &mh->coin_pub.eddsa_pub);
melt_obj = GNUNET_JSON_PACK ( melt_obj = GNUNET_JSON_PACK (
@ -357,7 +358,7 @@ start_melt (struct TALER_EXCHANGE_MeltHandle *mh)
GNUNET_JSON_pack_data_auto ("rc", GNUNET_JSON_pack_data_auto ("rc",
&mh->md.rc), &mh->md.rc),
GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_allow_null (
mh->md.melted_coin.h_age_commitment (NULL != mh->md.melted_coin.h_age_commitment)
? GNUNET_JSON_pack_data_auto ("age_commitment_hash", ? GNUNET_JSON_pack_data_auto ("age_commitment_hash",
mh->md.melted_coin.h_age_commitment) mh->md.melted_coin.h_age_commitment)
: GNUNET_JSON_pack_string ("age_commitment_hash", : GNUNET_JSON_pack_string ("age_commitment_hash",
@ -504,7 +505,6 @@ csr_cb (void *cls,
} }
/* FIXME: refactor this to use struct TALER_EXCHANGE_Handle */
struct TALER_EXCHANGE_MeltHandle * struct TALER_EXCHANGE_MeltHandle *
TALER_EXCHANGE_melt ( TALER_EXCHANGE_melt (
struct GNUNET_CURL_Context *ctx, struct GNUNET_CURL_Context *ctx,

View File

@ -45,6 +45,11 @@ TALER_EXCHANGE_free_melt_data_ (struct MeltData *md)
struct FreshCoinData *fcd = &md->fcds[j]; struct FreshCoinData *fcd = &md->fcds[j];
TALER_denom_pub_free (&fcd->fresh_pk); TALER_denom_pub_free (&fcd->fresh_pk);
for (size_t i = 0; i < TALER_CNC_KAPPA; i++)
{
TALER_age_commitment_proof_free (fcd->age_commitment_proofs[i]);
GNUNET_free (fcd->age_commitment_proofs[i]);
}
} }
GNUNET_free (md->fcds); GNUNET_free (md->fcds);
} }
@ -168,7 +173,8 @@ TALER_EXCHANGE_get_melt_data_ (
union TALER_DenominationBlindingKeyP *bks = &fcd->bks[i]; union TALER_DenominationBlindingKeyP *bks = &fcd->bks[i];
struct TALER_PlanchetDetail pd; struct TALER_PlanchetDetail pd;
struct TALER_CoinPubHashP c_hash; struct TALER_CoinPubHashP c_hash;
struct TALER_AgeCommitmentHash *ach = NULL; struct TALER_AgeCommitmentHash ach;
struct TALER_AgeCommitmentHash *pach = NULL;
TALER_transfer_secret_to_planchet_secret (&trans_sec, TALER_transfer_secret_to_planchet_secret (&trans_sec,
j, j,
@ -182,22 +188,21 @@ TALER_EXCHANGE_get_melt_data_ (
&alg_values[j], &alg_values[j],
bks); bks);
/* Handle age commitment, if present */ if (NULL != rd->melt_age_commitment_proof)
if (NULL != md->melted_coin.age_commitment_proof)
{ {
fcd->age_commitment_proof[i] = GNUNET_new (struct fcd->age_commitment_proofs[i] = GNUNET_new (struct
TALER_AgeCommitmentProof); TALER_AgeCommitmentProof);
ach = GNUNET_new (struct TALER_AgeCommitmentHash);
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_age_commitment_derive ( TALER_age_commitment_derive (
md->melted_coin.age_commitment_proof, md->melted_coin.age_commitment_proof,
&trans_sec.key, &trans_sec.key,
fcd->age_commitment_proof[i])); fcd->age_commitment_proofs[i]));
TALER_age_commitment_hash ( TALER_age_commitment_hash (
&fcd->age_commitment_proof[i]->commitment, &fcd->age_commitment_proofs[i]->commitment,
ach); &ach);
pach = &ach;
} }
if (TALER_DENOMINATION_CS == alg_values[j].cipher) if (TALER_DENOMINATION_CS == alg_values[j].cipher)
@ -208,7 +213,7 @@ TALER_EXCHANGE_get_melt_data_ (
&alg_values[j], &alg_values[j],
bks, bks,
coin_priv, coin_priv,
ach, pach,
&c_hash, &c_hash,
&pd)) &pd))
{ {

View File

@ -101,10 +101,9 @@ struct FreshCoinData
/** /**
* Arrays of age commitments and proofs to be created, one for each * Arrays of age commitments and proofs to be created, one for each
* cut-and-choose dimension. The entries in each list might be NULL and * cut-and-choose dimension. NULL if age restriction is not applicable.
* indicate no age commitment/restriction on the particular coin.
*/ */
struct TALER_AgeCommitmentProof *age_commitment_proof[TALER_CNC_KAPPA]; struct TALER_AgeCommitmentProof *age_commitment_proofs[TALER_CNC_KAPPA];
/** /**
* Blinding key secrets for the coins, depending on the * Blinding key secrets for the coins, depending on the

View File

@ -125,8 +125,7 @@ refresh_reveal_ok (struct TALER_EXCHANGE_RefreshesRevealHandle *rrh,
} }
for (unsigned int i = 0; i<rrh->md.num_fresh_coins; i++) for (unsigned int i = 0; i<rrh->md.num_fresh_coins; i++)
{ {
struct TALER_EXCHANGE_RevealedCoinInfo *rci = struct TALER_EXCHANGE_RevealedCoinInfo *rci = &rcis[i];
&rcis[i];
const struct FreshCoinData *fcd = &rrh->md.fcds[i]; const struct FreshCoinData *fcd = &rrh->md.fcds[i];
const struct TALER_DenominationPublicKey *pk; const struct TALER_DenominationPublicKey *pk;
json_t *jsonai; json_t *jsonai;
@ -140,25 +139,25 @@ refresh_reveal_ok (struct TALER_EXCHANGE_RefreshesRevealHandle *rrh,
}; };
struct TALER_FreshCoin coin; struct TALER_FreshCoin coin;
union TALER_DenominationBlindingKeyP bks; union TALER_DenominationBlindingKeyP bks;
const struct TALER_AgeCommitmentHash *pach = NULL;
rci->ps = fcd->ps[rrh->noreveal_index]; rci->ps = fcd->ps[rrh->noreveal_index];
rci->bks = fcd->bks[rrh->noreveal_index]; rci->bks = fcd->bks[rrh->noreveal_index];
rci->age_commitment_proof = fcd->age_commitment_proof[rrh->noreveal_index]; rci->age_commitment_proof = NULL;
rci->h_age_commitment = NULL;
pk = &fcd->fresh_pk; pk = &fcd->fresh_pk;
jsonai = json_array_get (jsona, i); jsonai = json_array_get (jsona, i);
GNUNET_assert (NULL != jsonai); GNUNET_assert (NULL != jsonai);
GNUNET_assert (
(NULL != rrh->md.melted_coin.age_commitment_proof) ==
(NULL != rci->age_commitment_proof));
if (NULL != rci->age_commitment_proof) if (NULL != rrh->md.melted_coin.age_commitment_proof)
{ {
rci->h_age_commitment = GNUNET_new (struct TALER_AgeCommitmentHash); rci->age_commitment_proof =
TALER_age_commitment_hash ( fcd->age_commitment_proofs[rrh->noreveal_index];
&rci->age_commitment_proof->commitment,
rci->h_age_commitment); TALER_age_commitment_hash (&rci->age_commitment_proof->commitment,
&rci->h_age_commitment);
pach = &rci->h_age_commitment;
} }
if (GNUNET_OK != if (GNUNET_OK !=
@ -180,18 +179,20 @@ refresh_reveal_ok (struct TALER_EXCHANGE_RefreshesRevealHandle *rrh,
hence recomputing it here... */ hence recomputing it here... */
GNUNET_CRYPTO_eddsa_key_get_public (&rci->coin_priv.eddsa_priv, GNUNET_CRYPTO_eddsa_key_get_public (&rci->coin_priv.eddsa_priv,
&coin_pub.eddsa_pub); &coin_pub.eddsa_pub);
TALER_coin_pub_hash (&coin_pub, TALER_coin_pub_hash (
rci->h_age_commitment, &coin_pub,
&coin_hash); pach,
&coin_hash);
if (GNUNET_OK != if (GNUNET_OK !=
TALER_planchet_to_coin (pk, TALER_planchet_to_coin (
&blind_sig, pk,
&bks, &blind_sig,
&rci->coin_priv, &bks,
rci->h_age_commitment, &rci->coin_priv,
&coin_hash, pach,
&rrh->alg_values[i], &coin_hash,
&coin)) &rrh->alg_values[i],
&coin))
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec); GNUNET_JSON_parse_free (spec);
@ -257,7 +258,10 @@ handle_refresh_reveal_finished (void *cls,
rrh->reveal_cb = NULL; rrh->reveal_cb = NULL;
} }
for (unsigned int i = 0; i<rrh->md.num_fresh_coins; i++) for (unsigned int i = 0; i<rrh->md.num_fresh_coins; i++)
{
TALER_denom_sig_free (&rcis[i].sig); TALER_denom_sig_free (&rcis[i].sig);
TALER_age_commitment_proof_free (rcis[i].age_commitment_proof);
}
TALER_EXCHANGE_refreshes_reveal_cancel (rrh); TALER_EXCHANGE_refreshes_reveal_cancel (rrh);
return; return;
} }
@ -303,7 +307,6 @@ handle_refresh_reveal_finished (void *cls,
} }
/* FIXME: refactor this to use struct TALER_EXCHANGE_Handle */
struct TALER_EXCHANGE_RefreshesRevealHandle * struct TALER_EXCHANGE_RefreshesRevealHandle *
TALER_EXCHANGE_refreshes_reveal ( TALER_EXCHANGE_refreshes_reveal (
struct GNUNET_CURL_Context *ctx, struct GNUNET_CURL_Context *ctx,
@ -408,20 +411,19 @@ TALER_EXCHANGE_refreshes_reveal (
} }
/* build array of old age commitment, if applicable */ /* build array of old age commitment, if applicable */
GNUNET_assert ((NULL == rd->melt_age_commitment_proof) ==
(NULL == rd->melt_h_age_commitment));
if (NULL != rd->melt_age_commitment_proof) if (NULL != rd->melt_age_commitment_proof)
{ {
GNUNET_assert (NULL != rd->melt_h_age_commitment);
GNUNET_assert (NULL != (old_age_commitment = json_array ())); GNUNET_assert (NULL != (old_age_commitment = json_array ()));
for (size_t i = 0; i < rd->melt_age_commitment_proof->commitment.num; i++) for (size_t i = 0; i < rd->melt_age_commitment_proof->commitment.num; i++)
{ {
GNUNET_assert (0 == enum GNUNET_GenericReturnValue ret;
json_array_append_new ( ret = json_array_append_new (
old_age_commitment, old_age_commitment,
GNUNET_JSON_from_data_auto ( GNUNET_JSON_from_data_auto (
&rd->melt_age_commitment_proof-> &rd->melt_age_commitment_proof->commitment.keys[i]));
commitment.keys[i]))); GNUNET_assert (0 == ret);
} }
} }

View File

@ -78,6 +78,9 @@ run (void *cls,
case TALER_TESTING_BS_IBAN: case TALER_TESTING_BS_IBAN:
ssoptions = "-ns"; ssoptions = "-ns";
break; break;
default:
ssoptions = NULL;
break;
} }
memset (&wtid, memset (&wtid,
42, 42,

View File

@ -660,7 +660,6 @@ run (void *cls,
"refresh-reveal-age-1", "refresh-reveal-age-1",
MHD_HTTP_CONFLICT, MHD_HTTP_CONFLICT,
NULL), NULL),
TALER_TESTING_cmd_end () TALER_TESTING_cmd_end ()
}; };

View File

@ -79,10 +79,10 @@ struct CoinState
/** /**
* If age > 0, put here the corresponding age commitment with its proof and * If age > 0, put here the corresponding age commitment with its proof and
* its hash, respectivelly, NULL otherwise. * its hash, respectivelly.
*/ */
struct TALER_AgeCommitmentProof *age_commitment_proof; struct TALER_AgeCommitmentProof age_commitment_proof;
struct TALER_AgeCommitmentHash *h_age_commitment; struct TALER_AgeCommitmentHash h_age_commitment;
/** /**
* Reserve history entry that corresponds to this coin. * Reserve history entry that corresponds to this coin.
@ -316,7 +316,7 @@ batch_withdraw_run (void *cls,
wci->pk = cs->pk; wci->pk = cs->pk;
wci->ps = &cs->ps; wci->ps = &cs->ps;
wci->ach = cs->h_age_commitment; wci->ach = &cs->h_age_commitment;
} }
ws->wsh = TALER_EXCHANGE_batch_withdraw ( ws->wsh = TALER_EXCHANGE_batch_withdraw (
TALER_TESTING_interpreter_get_context (is), TALER_TESTING_interpreter_get_context (is),
@ -366,13 +366,8 @@ batch_withdraw_cleanup (void *cls,
TALER_EXCHANGE_destroy_denomination_key (cs->pk); TALER_EXCHANGE_destroy_denomination_key (cs->pk);
cs->pk = NULL; cs->pk = NULL;
} }
if (NULL != cs->age_commitment_proof) if (0 < ws->age)
{ TALER_age_commitment_proof_free (&cs->age_commitment_proof);
TALER_age_commitment_proof_free (cs->age_commitment_proof);
cs->age_commitment_proof = NULL;
}
if (NULL != cs->h_age_commitment)
GNUNET_free (cs->h_age_commitment);
} }
GNUNET_free (ws->coins); GNUNET_free (ws->coins);
GNUNET_free (ws->exchange_url); GNUNET_free (ws->exchange_url);
@ -424,9 +419,13 @@ batch_withdraw_traits (void *cls,
TALER_TESTING_make_trait_payto_uri (ws->reserve_payto_uri), TALER_TESTING_make_trait_payto_uri (ws->reserve_payto_uri),
TALER_TESTING_make_trait_exchange_url (ws->exchange_url), TALER_TESTING_make_trait_exchange_url (ws->exchange_url),
TALER_TESTING_make_trait_age_commitment_proof (index, TALER_TESTING_make_trait_age_commitment_proof (index,
cs->age_commitment_proof), ws->age > 0 ?
&cs->age_commitment_proof:
NULL),
TALER_TESTING_make_trait_h_age_commitment (index, TALER_TESTING_make_trait_h_age_commitment (index,
cs->h_age_commitment), ws->age > 0 ?
&cs->h_age_commitment :
NULL),
TALER_TESTING_trait_end () TALER_TESTING_trait_end ()
}; };
@ -473,13 +472,9 @@ TALER_TESTING_cmd_batch_withdraw (const char *label,
if (0 < age) if (0 < age)
{ {
struct TALER_AgeCommitmentProof *acp;
struct TALER_AgeCommitmentHash *hac;
struct GNUNET_HashCode seed; struct GNUNET_HashCode seed;
struct TALER_AgeMask mask; struct TALER_AgeMask mask;
acp = GNUNET_new (struct TALER_AgeCommitmentProof);
hac = GNUNET_new (struct TALER_AgeCommitmentHash);
mask = TALER_extensions_get_age_restriction_mask (); mask = TALER_extensions_get_age_restriction_mask ();
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
&seed, &seed,
@ -490,7 +485,7 @@ TALER_TESTING_cmd_batch_withdraw (const char *label,
&mask, &mask,
age, age,
&seed, &seed,
acp)) &cs->age_commitment_proof))
{ {
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failed to generate age commitment for age %d at %s\n", "Failed to generate age commitment for age %d at %s\n",
@ -499,10 +494,8 @@ TALER_TESTING_cmd_batch_withdraw (const char *label,
GNUNET_assert (0); GNUNET_assert (0);
} }
TALER_age_commitment_hash (&acp->commitment, TALER_age_commitment_hash (&cs->age_commitment_proof.commitment,
hac); &cs->h_age_commitment);
cs->age_commitment_proof = acp;
cs->h_age_commitment = hac;
} }
if (GNUNET_OK != if (GNUNET_OK !=

View File

@ -284,8 +284,7 @@ deposit_run (void *cls,
const struct TALER_TESTING_Command *coin_cmd; const struct TALER_TESTING_Command *coin_cmd;
const struct TALER_CoinSpendPrivateKeyP *coin_priv; const struct TALER_CoinSpendPrivateKeyP *coin_priv;
struct TALER_CoinSpendPublicKeyP coin_pub; struct TALER_CoinSpendPublicKeyP coin_pub;
const struct TALER_AgeCommitmentProof *age_commitment_proof = NULL; const struct TALER_AgeCommitmentHash *phac;
struct TALER_AgeCommitmentHash h_age_commitment = {0};
const struct TALER_EXCHANGE_DenomPublicKey *denom_pub; const struct TALER_EXCHANGE_DenomPublicKey *denom_pub;
const struct TALER_DenominationSignature *denom_pub_sig; const struct TALER_DenominationSignature *denom_pub_sig;
struct TALER_CoinSpendSignatureP coin_sig; struct TALER_CoinSpendSignatureP coin_sig;
@ -389,9 +388,9 @@ deposit_run (void *cls,
ds->coin_index, ds->coin_index,
&coin_priv)) || &coin_priv)) ||
(GNUNET_OK != (GNUNET_OK !=
TALER_TESTING_get_trait_age_commitment_proof (coin_cmd, TALER_TESTING_get_trait_h_age_commitment (coin_cmd,
ds->coin_index, ds->coin_index,
&age_commitment_proof)) || &phac)) ||
(GNUNET_OK != (GNUNET_OK !=
TALER_TESTING_get_trait_denom_pub (coin_cmd, TALER_TESTING_get_trait_denom_pub (coin_cmd,
ds->coin_index, ds->coin_index,
@ -409,11 +408,6 @@ deposit_run (void *cls,
return; return;
} }
if (NULL != age_commitment_proof)
{
TALER_age_commitment_hash (&age_commitment_proof->commitment,
&h_age_commitment);
}
ds->deposit_fee = denom_pub->fees.deposit; ds->deposit_fee = denom_pub->fees.deposit;
GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv->eddsa_priv, GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv->eddsa_priv,
&coin_pub.eddsa_pub); &coin_pub.eddsa_pub);
@ -447,7 +441,7 @@ deposit_run (void *cls,
&denom_pub->fees.deposit, &denom_pub->fees.deposit,
&h_wire, &h_wire,
&h_contract_terms, &h_contract_terms,
&h_age_commitment, phac,
NULL, /* FIXME #7270: add hash of extensions */ NULL, /* FIXME #7270: add hash of extensions */
&denom_pub->h_key, &denom_pub->h_key,
ds->wallet_timestamp, ds->wallet_timestamp,
@ -460,11 +454,11 @@ deposit_run (void *cls,
{ {
struct TALER_EXCHANGE_CoinDepositDetail cdd = { struct TALER_EXCHANGE_CoinDepositDetail cdd = {
.amount = ds->amount, .amount = ds->amount,
.h_age_commitment = h_age_commitment,
.coin_pub = coin_pub, .coin_pub = coin_pub,
.coin_sig = coin_sig, .coin_sig = coin_sig,
.denom_sig = *denom_pub_sig, .denom_sig = *denom_pub_sig,
.h_denom_pub = denom_pub->h_key .h_denom_pub = denom_pub->h_key,
.h_age_commitment = {{{0}}},
}; };
struct TALER_EXCHANGE_DepositContractDetail dcd = { struct TALER_EXCHANGE_DepositContractDetail dcd = {
.wire_deadline = ds->wire_deadline, .wire_deadline = ds->wire_deadline,
@ -477,6 +471,9 @@ deposit_run (void *cls,
.refund_deadline = ds->refund_deadline .refund_deadline = ds->refund_deadline
}; };
if (NULL != phac)
cdd.h_age_commitment = *phac;
ds->dh = TALER_EXCHANGE_batch_deposit ( ds->dh = TALER_EXCHANGE_batch_deposit (
TALER_TESTING_interpreter_get_context (is), TALER_TESTING_interpreter_get_context (is),
exchange_url, exchange_url,
@ -551,6 +548,7 @@ deposit_traits (void *cls,
/* Will point to coin cmd internals. */ /* Will point to coin cmd internals. */
const struct TALER_CoinSpendPrivateKeyP *coin_spent_priv; const struct TALER_CoinSpendPrivateKeyP *coin_spent_priv;
const struct TALER_AgeCommitmentProof *age_commitment_proof; const struct TALER_AgeCommitmentProof *age_commitment_proof;
const struct TALER_AgeCommitmentHash *h_age_commitment;
if (GNUNET_YES != ds->command_initialized) if (GNUNET_YES != ds->command_initialized)
{ {
@ -575,12 +573,17 @@ deposit_traits (void *cls,
(GNUNET_OK != (GNUNET_OK !=
TALER_TESTING_get_trait_age_commitment_proof (coin_cmd, TALER_TESTING_get_trait_age_commitment_proof (coin_cmd,
ds->coin_index, ds->coin_index,
&age_commitment_proof)) ) &age_commitment_proof)) ||
(GNUNET_OK !=
TALER_TESTING_get_trait_h_age_commitment (coin_cmd,
ds->coin_index,
&h_age_commitment)) )
{ {
GNUNET_break (0); GNUNET_break (0);
TALER_TESTING_interpreter_fail (ds->is); TALER_TESTING_interpreter_fail (ds->is);
return GNUNET_NO; return GNUNET_NO;
} }
{ {
struct TALER_TESTING_Trait traits[] = { struct TALER_TESTING_Trait traits[] = {
/* First two traits are only available if /* First two traits are only available if
@ -594,6 +597,8 @@ deposit_traits (void *cls,
coin_spent_priv), coin_spent_priv),
TALER_TESTING_make_trait_age_commitment_proof (0, TALER_TESTING_make_trait_age_commitment_proof (0,
age_commitment_proof), age_commitment_proof),
TALER_TESTING_make_trait_h_age_commitment (0,
h_age_commitment),
TALER_TESTING_make_trait_wire_details (ds->wire_details), TALER_TESTING_make_trait_wire_details (ds->wire_details),
TALER_TESTING_make_trait_contract_terms (ds->contract_terms), TALER_TESTING_make_trait_contract_terms (ds->contract_terms),
TALER_TESTING_make_trait_merchant_priv (&ds->merchant_priv), TALER_TESTING_make_trait_merchant_priv (&ds->merchant_priv),

View File

@ -75,7 +75,7 @@ struct TALER_TESTING_FreshCoinData
* applicable. * applicable.
*/ */
struct TALER_AgeCommitmentProof *age_commitment_proof; struct TALER_AgeCommitmentProof *age_commitment_proof;
struct TALER_AgeCommitmentHash *h_age_commitment; struct TALER_AgeCommitmentHash h_age_commitment;
/** /**
* The blinding key (needed for recoup operations). * The blinding key (needed for recoup operations).
@ -440,8 +440,13 @@ reveal_cb (void *cls,
return; return;
} }
fc->coin_priv = coin->coin_priv; fc->coin_priv = coin->coin_priv;
fc->age_commitment_proof = coin->age_commitment_proof;
fc->h_age_commitment = coin->h_age_commitment; if (NULL != coin->age_commitment_proof)
{
fc->age_commitment_proof =
TALER_age_commitment_proof_duplicate (coin->age_commitment_proof);
fc->h_age_commitment = coin->h_age_commitment;
}
TALER_denom_sig_deep_copy (&fc->sig, TALER_denom_sig_deep_copy (&fc->sig,
&coin->sig); &coin->sig);
@ -559,7 +564,11 @@ refresh_reveal_cleanup (void *cls,
} }
for (unsigned int j = 0; j < rrs->num_fresh_coins; j++) for (unsigned int j = 0; j < rrs->num_fresh_coins; j++)
{
TALER_denom_sig_free (&rrs->fresh_coins[j].sig); TALER_denom_sig_free (&rrs->fresh_coins[j].sig);
TALER_age_commitment_proof_free (rrs->fresh_coins[j].age_commitment_proof);
GNUNET_free (rrs->fresh_coins[j].age_commitment_proof);
}
GNUNET_free (rrs->fresh_coins); GNUNET_free (rrs->fresh_coins);
GNUNET_free (rrs->psa); GNUNET_free (rrs->psa);
@ -1024,12 +1033,12 @@ melt_run (void *cls,
{ {
struct TALER_Amount melt_amount; struct TALER_Amount melt_amount;
struct TALER_Amount fresh_amount; struct TALER_Amount fresh_amount;
const struct TALER_AgeCommitmentProof *age_commitment_proof; const struct TALER_AgeCommitmentProof *age_commitment_proof = NULL;
const struct TALER_AgeCommitmentHash *h_age_commitment; const struct TALER_AgeCommitmentHash *h_age_commitment = NULL;
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; bool age_restricted_denom;
if (NULL == (coin_command if (NULL == (coin_command
= TALER_TESTING_interpreter_lookup_command ( = TALER_TESTING_interpreter_lookup_command (
@ -1094,7 +1103,10 @@ melt_run (void *cls,
/* 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->fees.refresh; melt_amount = melt_denom_pub->fees.refresh;
age_restricted = melt_denom_pub->key.age_mask.bits != 0; age_restricted_denom = melt_denom_pub->key.age_mask.bits != 0;
GNUNET_assert (age_restricted_denom == (NULL != age_commitment_proof));
GNUNET_assert ((NULL == age_commitment_proof) ||
(0 < age_commitment_proof->commitment.num));
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;
@ -1113,7 +1125,7 @@ melt_run (void *cls,
} }
fresh_pk = TALER_TESTING_find_pk (TALER_TESTING_get_keys (rms->is), fresh_pk = TALER_TESTING_find_pk (TALER_TESTING_get_keys (rms->is),
&fresh_amount, &fresh_amount,
age_restricted); age_restricted_denom);
if (NULL == fresh_pk) if (NULL == fresh_pk)
{ {
GNUNET_break (0); GNUNET_break (0);
@ -1139,13 +1151,20 @@ melt_run (void *cls,
rms->refresh_data.melt_amount = melt_amount; rms->refresh_data.melt_amount = melt_amount;
rms->refresh_data.melt_sig = *melt_sig; rms->refresh_data.melt_sig = *melt_sig;
rms->refresh_data.melt_pk = *melt_denom_pub; rms->refresh_data.melt_pk = *melt_denom_pub;
rms->refresh_data.melt_age_commitment_proof = age_commitment_proof;
rms->refresh_data.melt_h_age_commitment = h_age_commitment; if (NULL != age_commitment_proof)
{
GNUNET_assert (NULL != h_age_commitment);
rms->refresh_data.melt_age_commitment_proof = age_commitment_proof;
rms->refresh_data.melt_h_age_commitment = h_age_commitment;
}
rms->refresh_data.fresh_pks = rms->fresh_pks; rms->refresh_data.fresh_pks = rms->fresh_pks;
rms->refresh_data.fresh_pks_len = num_fresh_coins; rms->refresh_data.fresh_pks_len = num_fresh_coins;
GNUNET_assert (age_restricted == GNUNET_assert (age_restricted_denom ==
(NULL != age_commitment_proof)); (NULL != age_commitment_proof));
GNUNET_assert ((NULL == age_commitment_proof) ||
(0 < age_commitment_proof->commitment.num));
rms->rmh = TALER_EXCHANGE_melt ( rms->rmh = TALER_EXCHANGE_melt (
TALER_TESTING_interpreter_get_context (is), TALER_TESTING_interpreter_get_context (is),
@ -1198,6 +1217,7 @@ melt_cleanup (void *cls,
TALER_denom_pub_free (&rms->fresh_pks[i].key); TALER_denom_pub_free (&rms->fresh_pks[i].key);
GNUNET_free (rms->fresh_pks); GNUNET_free (rms->fresh_pks);
} }
GNUNET_free (rms->mbds); GNUNET_free (rms->mbds);
GNUNET_free (rms->melt_fresh_amounts); GNUNET_free (rms->melt_fresh_amounts);
GNUNET_free (rms); GNUNET_free (rms);
@ -1409,7 +1429,7 @@ refresh_reveal_traits (void *cls,
rrs->fresh_coins[index].age_commitment_proof), rrs->fresh_coins[index].age_commitment_proof),
TALER_TESTING_make_trait_h_age_commitment ( TALER_TESTING_make_trait_h_age_commitment (
index, index,
rrs->fresh_coins[index].h_age_commitment), &rrs->fresh_coins[index].h_age_commitment),
TALER_TESTING_make_trait_denom_pub ( TALER_TESTING_make_trait_denom_pub (
index, index,
rrs->fresh_coins[index].pk), rrs->fresh_coins[index].pk),
@ -1427,6 +1447,7 @@ refresh_reveal_traits (void *cls,
&rrs->psa[index]), &rrs->psa[index]),
TALER_TESTING_trait_end () TALER_TESTING_trait_end ()
}; };
return TALER_TESTING_get_trait (traits, return TALER_TESTING_get_trait (traits,
ret, ret,
trait, trait,

View File

@ -110,6 +110,7 @@ run_fakebank_cleanup (void *cls,
} }
GNUNET_free (rfs->ba.wire_gateway_url); GNUNET_free (rfs->ba.wire_gateway_url);
GNUNET_free (rfs->bank_url); GNUNET_free (rfs->bank_url);
GNUNET_free (rfs->currency);
GNUNET_free (rfs); GNUNET_free (rfs);
} }
@ -194,6 +195,7 @@ TALER_TESTING_cmd_run_fakebank (
(unsigned int) fakebank_port, (unsigned int) fakebank_port,
exchange_xtalerbank_account); exchange_xtalerbank_account);
GNUNET_free (exchange_xtalerbank_account); GNUNET_free (exchange_xtalerbank_account);
GNUNET_free (exchange_payto_uri);
} }
rfs->ba.method = TALER_BANK_AUTH_NONE; rfs->ba.method = TALER_BANK_AUTH_NONE;
{ {

View File

@ -144,10 +144,10 @@ struct WithdrawState
/** /**
* If age > 0, put here the corresponding age commitment with its proof and * If age > 0, put here the corresponding age commitment with its proof and
* its hash, respectivelly, NULL otherwise. * its hash, respectivelly.
*/ */
struct TALER_AgeCommitmentProof *age_commitment_proof; struct TALER_AgeCommitmentProof age_commitment_proof;
struct TALER_AgeCommitmentHash *h_age_commitment; struct TALER_AgeCommitmentHash h_age_commitment;
/** /**
* Reserve history entry that corresponds to this operation. * Reserve history entry that corresponds to this operation.
@ -438,7 +438,7 @@ withdraw_run (void *cls,
struct TALER_EXCHANGE_WithdrawCoinInput wci = { struct TALER_EXCHANGE_WithdrawCoinInput wci = {
.pk = ws->pk, .pk = ws->pk,
.ps = &ws->ps, .ps = &ws->ps,
.ach = ws->h_age_commitment .ach = 0 < ws->age ? &ws->h_age_commitment : NULL
}; };
ws->wsh = TALER_EXCHANGE_withdraw ( ws->wsh = TALER_EXCHANGE_withdraw (
TALER_TESTING_interpreter_get_context (is), TALER_TESTING_interpreter_get_context (is),
@ -489,16 +489,8 @@ withdraw_cleanup (void *cls,
TALER_EXCHANGE_destroy_denomination_key (ws->pk); TALER_EXCHANGE_destroy_denomination_key (ws->pk);
ws->pk = NULL; ws->pk = NULL;
} }
if (NULL != ws->age_commitment_proof) if (ws->age > 0)
{ TALER_age_commitment_proof_free (&ws->age_commitment_proof);
TALER_age_commitment_proof_free (ws->age_commitment_proof);
ws->age_commitment_proof = NULL;
}
if (NULL != ws->h_age_commitment)
{
GNUNET_free (ws->h_age_commitment);
ws->h_age_commitment = NULL;
}
GNUNET_free (ws->exchange_url); GNUNET_free (ws->exchange_url);
GNUNET_free (ws->reserve_payto_uri); GNUNET_free (ws->reserve_payto_uri);
GNUNET_free (ws); GNUNET_free (ws);
@ -545,9 +537,13 @@ withdraw_traits (void *cls,
TALER_TESTING_make_trait_payto_uri (ws->reserve_payto_uri), TALER_TESTING_make_trait_payto_uri (ws->reserve_payto_uri),
TALER_TESTING_make_trait_exchange_url (ws->exchange_url), TALER_TESTING_make_trait_exchange_url (ws->exchange_url),
TALER_TESTING_make_trait_age_commitment_proof (0, TALER_TESTING_make_trait_age_commitment_proof (0,
ws->age_commitment_proof), 0 < ws->age
? &ws->age_commitment_proof
: NULL),
TALER_TESTING_make_trait_h_age_commitment (0, TALER_TESTING_make_trait_h_age_commitment (0,
ws->h_age_commitment), 0 < ws->age
? &ws->h_age_commitment
: NULL),
TALER_TESTING_trait_end () TALER_TESTING_trait_end ()
}; };
@ -573,13 +569,9 @@ TALER_TESTING_cmd_withdraw_amount (const char *label,
ws->age = age; ws->age = age;
if (0 < age) if (0 < age)
{ {
struct TALER_AgeCommitmentProof *acp;
struct TALER_AgeCommitmentHash *hac;
struct GNUNET_HashCode seed; struct GNUNET_HashCode seed;
struct TALER_AgeMask mask; struct TALER_AgeMask mask;
acp = GNUNET_new (struct TALER_AgeCommitmentProof);
hac = GNUNET_new (struct TALER_AgeCommitmentHash);
mask = TALER_extensions_get_age_restriction_mask (); mask = TALER_extensions_get_age_restriction_mask ();
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
&seed, &seed,
@ -590,7 +582,7 @@ TALER_TESTING_cmd_withdraw_amount (const char *label,
&mask, &mask,
age, age,
&seed, &seed,
acp)) &ws->age_commitment_proof))
{ {
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failed to generate age commitment for age %d at %s\n", "Failed to generate age commitment for age %d at %s\n",
@ -598,10 +590,8 @@ TALER_TESTING_cmd_withdraw_amount (const char *label,
label); label);
GNUNET_assert (0); GNUNET_assert (0);
} }
TALER_age_commitment_hash (&acp->commitment, TALER_age_commitment_hash (&ws->age_commitment_proof.commitment,
hac); &ws->h_age_commitment);
ws->age_commitment_proof = acp;
ws->h_age_commitment = hac;
} }
ws->reserve_reference = reserve_reference; ws->reserve_reference = reserve_reference;

View File

@ -464,6 +464,9 @@ void
TALER_age_proof_free ( TALER_age_proof_free (
struct TALER_AgeProof *proof) struct TALER_AgeProof *proof)
{ {
if (NULL == proof)
return;
if (NULL != proof->keys) if (NULL != proof->keys)
{ {
GNUNET_CRYPTO_zero_keys ( GNUNET_CRYPTO_zero_keys (
@ -479,26 +482,71 @@ TALER_age_proof_free (
void void
TALER_age_commitment_proof_free ( TALER_age_commitment_proof_free (
struct TALER_AgeCommitmentProof *cp) struct TALER_AgeCommitmentProof *acp)
{ {
if (NULL != cp->proof.keys) if (NULL == acp)
return;
if (NULL != acp->proof.keys)
{ {
GNUNET_CRYPTO_zero_keys ( GNUNET_CRYPTO_zero_keys (
cp->proof.keys, acp->proof.keys,
sizeof(*cp->proof.keys) * cp->proof.num); sizeof(*acp->proof.keys) * acp->proof.num);
GNUNET_free (cp->proof.keys); GNUNET_free (acp->proof.keys);
cp->proof.keys = NULL; acp->proof.keys = NULL;
} }
if (NULL != cp->commitment.keys) if (NULL != acp->commitment.keys)
{ {
GNUNET_free (cp->commitment.keys); GNUNET_free (acp->commitment.keys);
cp->commitment.keys = NULL; acp->commitment.keys = NULL;
} }
} }
struct TALER_AgeCommitmentProof *
TALER_age_commitment_proof_duplicate (
const struct TALER_AgeCommitmentProof *acp)
{
struct TALER_AgeCommitmentProof *nacp;
GNUNET_assert (NULL != acp);
GNUNET_assert (__builtin_popcount (acp->commitment.mask.bits) - 1 ==
(int) acp->commitment.num);
nacp = GNUNET_new (struct TALER_AgeCommitmentProof);
TALER_age_commitment_proof_deep_copy (acp,nacp);
return nacp;
}
void
TALER_age_commitment_proof_deep_copy (
const struct TALER_AgeCommitmentProof *acp,
struct TALER_AgeCommitmentProof *nacp)
{
GNUNET_assert (NULL != acp);
GNUNET_assert (__builtin_popcount (acp->commitment.mask.bits) - 1 ==
(int) acp->commitment.num);
*nacp = *acp;
nacp->commitment.keys =
GNUNET_new_array (acp->commitment.num,
struct TALER_AgeCommitmentPublicKeyP);
nacp->proof.keys =
GNUNET_new_array (acp->proof.num,
struct TALER_AgeCommitmentPrivateKeyP);
for (size_t i = 0; i < acp->commitment.num; i++)
nacp->commitment.keys[i] = acp->commitment.keys[i];
for (size_t i = 0; i < acp->proof.num; i++)
nacp->proof.keys[i] = acp->proof.keys[i];
}
enum GNUNET_GenericReturnValue enum GNUNET_GenericReturnValue
TALER_JSON_parse_age_groups (const json_t *root, TALER_JSON_parse_age_groups (const json_t *root,
struct TALER_AgeMask *mask) struct TALER_AgeMask *mask)
@ -571,19 +619,16 @@ TALER_parse_age_group_string (
} }
char * const char *
TALER_age_mask_to_string ( TALER_age_mask_to_string (
const struct TALER_AgeMask *mask) const struct TALER_AgeMask *mask)
{ {
static char buf[256] = {0};
uint32_t bits = mask->bits; uint32_t bits = mask->bits;
unsigned int n = 0; unsigned int n = 0;
char *buf = GNUNET_malloc (32 * 3); // max characters possible
char *pos = buf; char *pos = buf;
if (NULL == buf) memset (buf, 0, sizeof(buf));
{
return buf;
}
while (bits != 0) while (bits != 0)
{ {