gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-exchange] 03/04: fix memory leaks reported by valgrind


From: gnunet
Subject: [taler-exchange] 03/04: fix memory leaks reported by valgrind
Date: Mon, 10 Jul 2023 10:28:41 +0200

This is an automated email from the git hooks/post-receive script.

oec pushed a commit to branch master
in repository exchange.

commit 3024dc9fa54e8677b4816e56f8d215556a7d5561
Author: Özgür Kesim <oec-taler@kesim.org>
AuthorDate: Mon Jul 10 10:23:52 2023 +0200

    fix memory leaks reported by valgrind
---
 src/extensions/extensions.c                  | 13 +++--
 src/include/taler_crypto_lib.h               | 33 +++++++++---
 src/include/taler_exchange_service.h         |  9 ++--
 src/include/taler_util.h                     |  7 ++-
 src/lib/exchange_api_link.c                  | 33 ++++++------
 src/lib/exchange_api_melt.c                  | 18 +++----
 src/lib/exchange_api_refresh_common.c        | 25 ++++++----
 src/lib/exchange_api_refresh_common.h        |  5 +-
 src/lib/exchange_api_refreshes_reveal.c      | 66 ++++++++++++------------
 src/testing/test_bank_api.c                  |  3 ++
 src/testing/test_exchange_api.c              |  1 -
 src/testing/testing_api_cmd_batch_withdraw.c | 37 ++++++--------
 src/testing/testing_api_cmd_deposit.c        | 33 ++++++------
 src/testing/testing_api_cmd_refresh.c        | 45 ++++++++++++-----
 src/testing/testing_api_cmd_run_fakebank.c   |  2 +
 src/testing/testing_api_cmd_withdraw.c       | 40 ++++++---------
 src/util/age_restriction.c                   | 75 ++++++++++++++++++++++------
 17 files changed, 269 insertions(+), 176 deletions(-)

diff --git a/src/extensions/extensions.c b/src/extensions/extensions.c
index 731ccfd0..fbbe874f 100644
--- a/src/extensions/extensions.c
+++ b/src/extensions/extensions.c
@@ -184,7 +184,7 @@ configure_extension (
 {
   struct LoadConfClosure *col = cls;
   const char *name;
-  char *lib_name;
+  char lib_name[1024] = {0};
   struct TALER_Extension *extension;
 
   if (GNUNET_OK != col->error)
@@ -199,17 +199,16 @@ configure_extension (
 
 
   /* Load the extension library */
-  GNUNET_asprintf (&lib_name,
+  GNUNET_snprintf (lib_name,
+                   sizeof(lib_name),
                    "libtaler_extension_%s",
                    name);
   /* Lower-case extension name, config is case-insensitive */
   for (unsigned int i = 0; i < strlen (lib_name); i++)
-  {
     lib_name[i] = tolower (lib_name[i]);
-  }
-  extension = GNUNET_PLUGIN_load (
-    lib_name,
-    (void *) col->cfg);
+
+  extension = GNUNET_PLUGIN_load (lib_name,
+                                  (void *) col->cfg);
   if (NULL == extension)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h
index 3ad441cb..373fc5c2 100644
--- a/src/include/taler_crypto_lib.h
+++ b/src/include/taler_crypto_lib.h
@@ -5947,33 +5947,54 @@ TALER_age_commitment_verify (
 /**
  * @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
 TALER_age_commitment_free (
-  struct TALER_AgeCommitment *p);
+  struct TALER_AgeCommitment *ac);
 
 
 /**
  * @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
 TALER_age_proof_free (
-  struct TALER_AgeProof *p);
+  struct TALER_AgeProof *ap);
 
 
 /**
  * @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
 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
  * age groups larger than the allowed maximum age group are derived by scalar
diff --git a/src/include/taler_exchange_service.h 
b/src/include/taler_exchange_service.h
index 35a68872..aedd2fcf 100644
--- a/src/include/taler_exchange_service.h
+++ b/src/include/taler_exchange_service.h
@@ -3043,7 +3043,7 @@ struct TALER_EXCHANGE_RevealedCoinInfo
    * Age commitment and its hash of the coin, might be NULL.
    */
   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.
@@ -3187,10 +3187,11 @@ struct TALER_EXCHANGE_LinkedCoinInfo
   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;
-  struct TALER_AgeCommitmentHash *h_age_commitment;
+  bool has_age_commitment;
+  struct TALER_AgeCommitmentProof age_commitment_proof;
+  struct TALER_AgeCommitmentHash h_age_commitment;
 
   /**
    * Master secret of this coin.
diff --git a/src/include/taler_util.h b/src/include/taler_util.h
index e0473bff..8762f7dc 100644
--- a/src/include/taler_util.h
+++ b/src/include/taler_util.h
@@ -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"
  *
+ * NOTE: This function uses a static buffer.  It is not safe to call this
+ * function concurrently.
+ *
  * @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.
  */
-char *
+const char *
 TALER_age_mask_to_string (
   const struct TALER_AgeMask *mask);
 
diff --git a/src/lib/exchange_api_link.c b/src/lib/exchange_api_link.c
index 04beeb29..86637683 100644
--- a/src/lib/exchange_api_link.c
+++ b/src/lib/exchange_api_link.c
@@ -114,6 +114,7 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh,
   struct TALER_TransferSecretP secret;
   struct TALER_PlanchetDetail pd;
   struct TALER_CoinPubHashP c_hash;
+  struct TALER_AgeCommitmentHash *pach = NULL;
 
   /* parse reply */
   if (GNUNET_OK !=
@@ -137,34 +138,35 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle 
*lh,
                                          &alg_values,
                                          &bks);
 
-  lci->age_commitment_proof = NULL;
-  lci->h_age_commitment = NULL;
+  lci->has_age_commitment = false;
 
   /* Derive the age commitment and calculate the hash */
   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 ==
                    TALER_age_commitment_derive (
                      lh->age_commitment_proof,
                      &secret.key,
-                     lci->age_commitment_proof));
+                     &lci->age_commitment_proof));
 
     TALER_age_commitment_hash (
-      &(lci->age_commitment_proof->commitment),
-      lci->h_age_commitment);
+      &lci->age_commitment_proof.commitment,
+      &lci->h_age_commitment);
+
+    lci->has_age_commitment = true;
+    pach = &lci->h_age_commitment;
   }
 
   if (GNUNET_OK !=
-      TALER_planchet_prepare (&rpub,
-                              &alg_values,
-                              &bks,
-                              &lci->coin_priv,
-                              lci->h_age_commitment,
-                              &c_hash,
-                              &pd))
+      TALER_planchet_prepare (
+        &rpub,
+        &alg_values,
+        &bks,
+        &lci->coin_priv,
+        pach,
+        &c_hash,
+        &pd))
   {
     GNUNET_break (0);
     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_pub_free (&lcis[i].pub);
+      if (lcis[i].has_age_commitment)
+        TALER_age_commitment_proof_free (&lcis[i].age_commitment_proof);
     }
   }
   return ret;
@@ -513,6 +517,7 @@ TALER_EXCHANGE_link_cancel (struct 
TALER_EXCHANGE_LinkHandle *lh)
     GNUNET_CURL_job_cancel (lh->job);
     lh->job = NULL;
   }
+
   GNUNET_free (lh->url);
   GNUNET_free (lh);
 }
diff --git a/src/lib/exchange_api_melt.c b/src/lib/exchange_api_melt.c
index f19f98c5..7fbd2114 100644
--- a/src/lib/exchange_api_melt.c
+++ b/src/lib/exchange_api_melt.c
@@ -336,13 +336,14 @@ start_melt (struct TALER_EXCHANGE_MeltHandle *mh)
   }
   TALER_denom_pub_hash (&mh->md.melted_coin.pub_key,
                         &h_denom_pub);
-  TALER_wallet_melt_sign (&mh->md.melted_coin.melt_amount_with_fee,
-                          &mh->md.melted_coin.fee_melt,
-                          &mh->md.rc,
-                          &h_denom_pub,
-                          mh->md.melted_coin.h_age_commitment,
-                          &mh->md.melted_coin.coin_priv,
-                          &mh->coin_sig);
+  TALER_wallet_melt_sign (
+    &mh->md.melted_coin.melt_amount_with_fee,
+    &mh->md.melted_coin.fee_melt,
+    &mh->md.rc,
+    &h_denom_pub,
+    mh->md.melted_coin.h_age_commitment,
+    &mh->md.melted_coin.coin_priv,
+    &mh->coin_sig);
   GNUNET_CRYPTO_eddsa_key_get_public (&mh->md.melted_coin.coin_priv.eddsa_priv,
                                       &mh->coin_pub.eddsa_pub);
   melt_obj = GNUNET_JSON_PACK (
@@ -357,7 +358,7 @@ start_melt (struct TALER_EXCHANGE_MeltHandle *mh)
     GNUNET_JSON_pack_data_auto ("rc",
                                 &mh->md.rc),
     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",
                                     mh->md.melted_coin.h_age_commitment)
       : 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 *
 TALER_EXCHANGE_melt (
   struct GNUNET_CURL_Context *ctx,
diff --git a/src/lib/exchange_api_refresh_common.c 
b/src/lib/exchange_api_refresh_common.c
index 581e2115..04c58022 100644
--- a/src/lib/exchange_api_refresh_common.c
+++ b/src/lib/exchange_api_refresh_common.c
@@ -45,6 +45,11 @@ TALER_EXCHANGE_free_melt_data_ (struct MeltData *md)
       struct FreshCoinData *fcd = &md->fcds[j];
 
       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);
   }
@@ -168,7 +173,8 @@ TALER_EXCHANGE_get_melt_data_ (
       union TALER_DenominationBlindingKeyP *bks = &fcd->bks[i];
       struct TALER_PlanchetDetail pd;
       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,
                                                 j,
@@ -182,22 +188,21 @@ TALER_EXCHANGE_get_melt_data_ (
                                              &alg_values[j],
                                              bks);
 
-      /* Handle age commitment, if present */
-      if (NULL != md->melted_coin.age_commitment_proof)
+      if (NULL != rd->melt_age_commitment_proof)
       {
-        fcd->age_commitment_proof[i] = GNUNET_new (struct
-                                                   TALER_AgeCommitmentProof);
-        ach = GNUNET_new (struct TALER_AgeCommitmentHash);
+        fcd->age_commitment_proofs[i] = GNUNET_new (struct
+                                                    TALER_AgeCommitmentProof);
 
         GNUNET_assert (GNUNET_OK ==
                        TALER_age_commitment_derive (
                          md->melted_coin.age_commitment_proof,
                          &trans_sec.key,
-                         fcd->age_commitment_proof[i]));
+                         fcd->age_commitment_proofs[i]));
 
         TALER_age_commitment_hash (
-          &fcd->age_commitment_proof[i]->commitment,
-          ach);
+          &fcd->age_commitment_proofs[i]->commitment,
+          &ach);
+        pach = &ach;
       }
 
       if (TALER_DENOMINATION_CS == alg_values[j].cipher)
@@ -208,7 +213,7 @@ TALER_EXCHANGE_get_melt_data_ (
                                   &alg_values[j],
                                   bks,
                                   coin_priv,
-                                  ach,
+                                  pach,
                                   &c_hash,
                                   &pd))
       {
diff --git a/src/lib/exchange_api_refresh_common.h 
b/src/lib/exchange_api_refresh_common.h
index c06824fe..0cb80f17 100644
--- a/src/lib/exchange_api_refresh_common.h
+++ b/src/lib/exchange_api_refresh_common.h
@@ -101,10 +101,9 @@ struct FreshCoinData
 
   /**
    * 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
-   * indicate no age commitment/restriction on the particular coin.
+   * cut-and-choose dimension.  NULL if age restriction is not applicable.
    */
-  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
diff --git a/src/lib/exchange_api_refreshes_reveal.c 
b/src/lib/exchange_api_refreshes_reveal.c
index 291c3be1..3360accd 100644
--- a/src/lib/exchange_api_refreshes_reveal.c
+++ b/src/lib/exchange_api_refreshes_reveal.c
@@ -125,8 +125,7 @@ refresh_reveal_ok (struct 
TALER_EXCHANGE_RefreshesRevealHandle *rrh,
   }
   for (unsigned int i = 0; i<rrh->md.num_fresh_coins; i++)
   {
-    struct TALER_EXCHANGE_RevealedCoinInfo *rci =
-      &rcis[i];
+    struct TALER_EXCHANGE_RevealedCoinInfo *rci = &rcis[i];
     const struct FreshCoinData *fcd = &rrh->md.fcds[i];
     const struct TALER_DenominationPublicKey *pk;
     json_t *jsonai;
@@ -140,25 +139,25 @@ refresh_reveal_ok (struct 
TALER_EXCHANGE_RefreshesRevealHandle *rrh,
     };
     struct TALER_FreshCoin coin;
     union TALER_DenominationBlindingKeyP bks;
+    const struct TALER_AgeCommitmentHash *pach = NULL;
 
     rci->ps = fcd->ps[rrh->noreveal_index];
     rci->bks = fcd->bks[rrh->noreveal_index];
-    rci->age_commitment_proof = fcd->age_commitment_proof[rrh->noreveal_index];
-    rci->h_age_commitment = NULL;
+    rci->age_commitment_proof = NULL;
+
     pk = &fcd->fresh_pk;
     jsonai = json_array_get (jsona, i);
 
     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);
-      TALER_age_commitment_hash (
-        &rci->age_commitment_proof->commitment,
-        rci->h_age_commitment);
+      rci->age_commitment_proof =
+        fcd->age_commitment_proofs[rrh->noreveal_index];
+
+      TALER_age_commitment_hash (&rci->age_commitment_proof->commitment,
+                                 &rci->h_age_commitment);
+      pach = &rci->h_age_commitment;
     }
 
     if (GNUNET_OK !=
@@ -180,18 +179,20 @@ refresh_reveal_ok (struct 
TALER_EXCHANGE_RefreshesRevealHandle *rrh,
        hence recomputing it here... */
     GNUNET_CRYPTO_eddsa_key_get_public (&rci->coin_priv.eddsa_priv,
                                         &coin_pub.eddsa_pub);
-    TALER_coin_pub_hash (&coin_pub,
-                         rci->h_age_commitment,
-                         &coin_hash);
+    TALER_coin_pub_hash (
+      &coin_pub,
+      pach,
+      &coin_hash);
     if (GNUNET_OK !=
-        TALER_planchet_to_coin (pk,
-                                &blind_sig,
-                                &bks,
-                                &rci->coin_priv,
-                                rci->h_age_commitment,
-                                &coin_hash,
-                                &rrh->alg_values[i],
-                                &coin))
+        TALER_planchet_to_coin (
+          pk,
+          &blind_sig,
+          &bks,
+          &rci->coin_priv,
+          pach,
+          &coin_hash,
+          &rrh->alg_values[i],
+          &coin))
     {
       GNUNET_break_op (0);
       GNUNET_JSON_parse_free (spec);
@@ -257,7 +258,10 @@ handle_refresh_reveal_finished (void *cls,
         rrh->reveal_cb = NULL;
       }
       for (unsigned int i = 0; i<rrh->md.num_fresh_coins; i++)
+      {
         TALER_denom_sig_free (&rcis[i].sig);
+        TALER_age_commitment_proof_free (rcis[i].age_commitment_proof);
+      }
       TALER_EXCHANGE_refreshes_reveal_cancel (rrh);
       return;
     }
@@ -303,7 +307,6 @@ handle_refresh_reveal_finished (void *cls,
 }
 
 
-/* FIXME: refactor this to use struct TALER_EXCHANGE_Handle */
 struct TALER_EXCHANGE_RefreshesRevealHandle *
 TALER_EXCHANGE_refreshes_reveal (
   struct GNUNET_CURL_Context *ctx,
@@ -408,20 +411,19 @@ TALER_EXCHANGE_refreshes_reveal (
   }
 
   /* 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)
   {
+    GNUNET_assert (NULL != rd->melt_h_age_commitment);
     GNUNET_assert (NULL != (old_age_commitment = json_array ()));
 
     for (size_t i = 0; i < rd->melt_age_commitment_proof->commitment.num; i++)
     {
-      GNUNET_assert (0 ==
-                     json_array_append_new (
-                       old_age_commitment,
-                       GNUNET_JSON_from_data_auto (
-                         &rd->melt_age_commitment_proof->
-                         commitment.keys[i])));
+      enum GNUNET_GenericReturnValue ret;
+      ret = json_array_append_new (
+        old_age_commitment,
+        GNUNET_JSON_from_data_auto (
+          &rd->melt_age_commitment_proof->commitment.keys[i]));
+      GNUNET_assert (0 == ret);
     }
   }
 
diff --git a/src/testing/test_bank_api.c b/src/testing/test_bank_api.c
index e197b152..8f1fe296 100644
--- a/src/testing/test_bank_api.c
+++ b/src/testing/test_bank_api.c
@@ -78,6 +78,9 @@ run (void *cls,
   case TALER_TESTING_BS_IBAN:
     ssoptions = "-ns";
     break;
+  default:
+    ssoptions = NULL;
+    break;
   }
   memset (&wtid,
           42,
diff --git a/src/testing/test_exchange_api.c b/src/testing/test_exchange_api.c
index e8cc6659..8ecf5d5b 100644
--- a/src/testing/test_exchange_api.c
+++ b/src/testing/test_exchange_api.c
@@ -660,7 +660,6 @@ run (void *cls,
                             "refresh-reveal-age-1",
                             MHD_HTTP_CONFLICT,
                             NULL),
-
     TALER_TESTING_cmd_end ()
   };
 
diff --git a/src/testing/testing_api_cmd_batch_withdraw.c 
b/src/testing/testing_api_cmd_batch_withdraw.c
index 184e02bf..da43a9aa 100644
--- a/src/testing/testing_api_cmd_batch_withdraw.c
+++ b/src/testing/testing_api_cmd_batch_withdraw.c
@@ -79,10 +79,10 @@ struct CoinState
 
   /**
    * 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_AgeCommitmentHash *h_age_commitment;
+  struct TALER_AgeCommitmentProof age_commitment_proof;
+  struct TALER_AgeCommitmentHash h_age_commitment;
 
   /**
    * Reserve history entry that corresponds to this coin.
@@ -316,7 +316,7 @@ batch_withdraw_run (void *cls,
 
     wci->pk = cs->pk;
     wci->ps = &cs->ps;
-    wci->ach = cs->h_age_commitment;
+    wci->ach = &cs->h_age_commitment;
   }
   ws->wsh = TALER_EXCHANGE_batch_withdraw (
     TALER_TESTING_interpreter_get_context (is),
@@ -366,13 +366,8 @@ batch_withdraw_cleanup (void *cls,
       TALER_EXCHANGE_destroy_denomination_key (cs->pk);
       cs->pk = NULL;
     }
-    if (NULL != 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);
+    if (0 < ws->age)
+      TALER_age_commitment_proof_free (&cs->age_commitment_proof);
   }
   GNUNET_free (ws->coins);
   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_exchange_url (ws->exchange_url),
     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,
-                                               cs->h_age_commitment),
+                                               ws->age > 0 ?
+                                               &cs->h_age_commitment :
+                                               NULL),
     TALER_TESTING_trait_end ()
   };
 
@@ -473,13 +472,9 @@ TALER_TESTING_cmd_batch_withdraw (const char *label,
 
     if (0 < age)
     {
-      struct TALER_AgeCommitmentProof *acp;
-      struct TALER_AgeCommitmentHash *hac;
       struct GNUNET_HashCode seed;
       struct TALER_AgeMask mask;
 
-      acp = GNUNET_new (struct TALER_AgeCommitmentProof);
-      hac = GNUNET_new (struct TALER_AgeCommitmentHash);
       mask = TALER_extensions_get_age_restriction_mask ();
       GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
                                   &seed,
@@ -490,7 +485,7 @@ TALER_TESTING_cmd_batch_withdraw (const char *label,
             &mask,
             age,
             &seed,
-            acp))
+            &cs->age_commitment_proof))
       {
         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                     "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);
       }
 
-      TALER_age_commitment_hash (&acp->commitment,
-                                 hac);
-      cs->age_commitment_proof = acp;
-      cs->h_age_commitment = hac;
+      TALER_age_commitment_hash (&cs->age_commitment_proof.commitment,
+                                 &cs->h_age_commitment);
     }
 
     if (GNUNET_OK !=
diff --git a/src/testing/testing_api_cmd_deposit.c 
b/src/testing/testing_api_cmd_deposit.c
index 2fa0141f..5c98f91a 100644
--- a/src/testing/testing_api_cmd_deposit.c
+++ b/src/testing/testing_api_cmd_deposit.c
@@ -284,8 +284,7 @@ deposit_run (void *cls,
   const struct TALER_TESTING_Command *coin_cmd;
   const struct TALER_CoinSpendPrivateKeyP *coin_priv;
   struct TALER_CoinSpendPublicKeyP coin_pub;
-  const struct TALER_AgeCommitmentProof *age_commitment_proof = NULL;
-  struct TALER_AgeCommitmentHash h_age_commitment = {0};
+  const struct TALER_AgeCommitmentHash *phac;
   const struct TALER_EXCHANGE_DenomPublicKey *denom_pub;
   const struct TALER_DenominationSignature *denom_pub_sig;
   struct TALER_CoinSpendSignatureP coin_sig;
@@ -389,9 +388,9 @@ deposit_run (void *cls,
                                            ds->coin_index,
                                            &coin_priv)) ||
        (GNUNET_OK !=
-        TALER_TESTING_get_trait_age_commitment_proof (coin_cmd,
-                                                      ds->coin_index,
-                                                      &age_commitment_proof)) 
||
+        TALER_TESTING_get_trait_h_age_commitment (coin_cmd,
+                                                  ds->coin_index,
+                                                  &phac)) ||
        (GNUNET_OK !=
         TALER_TESTING_get_trait_denom_pub (coin_cmd,
                                            ds->coin_index,
@@ -409,11 +408,6 @@ deposit_run (void *cls,
     return;
   }
 
-  if (NULL != age_commitment_proof)
-  {
-    TALER_age_commitment_hash (&age_commitment_proof->commitment,
-                               &h_age_commitment);
-  }
   ds->deposit_fee = denom_pub->fees.deposit;
   GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv->eddsa_priv,
                                       &coin_pub.eddsa_pub);
@@ -447,7 +441,7 @@ deposit_run (void *cls,
                                &denom_pub->fees.deposit,
                                &h_wire,
                                &h_contract_terms,
-                               &h_age_commitment,
+                               phac,
                                NULL, /* FIXME #7270: add hash of extensions */
                                &denom_pub->h_key,
                                ds->wallet_timestamp,
@@ -460,11 +454,11 @@ deposit_run (void *cls,
   {
     struct TALER_EXCHANGE_CoinDepositDetail cdd = {
       .amount = ds->amount,
-      .h_age_commitment = h_age_commitment,
       .coin_pub = coin_pub,
       .coin_sig = coin_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 = {
       .wire_deadline = ds->wire_deadline,
@@ -477,6 +471,9 @@ deposit_run (void *cls,
       .refund_deadline = ds->refund_deadline
     };
 
+    if (NULL != phac)
+      cdd.h_age_commitment = *phac;
+
     ds->dh = TALER_EXCHANGE_batch_deposit (
       TALER_TESTING_interpreter_get_context (is),
       exchange_url,
@@ -551,6 +548,7 @@ deposit_traits (void *cls,
   /* Will point to coin cmd internals. */
   const struct TALER_CoinSpendPrivateKeyP *coin_spent_priv;
   const struct TALER_AgeCommitmentProof *age_commitment_proof;
+  const struct TALER_AgeCommitmentHash *h_age_commitment;
 
   if (GNUNET_YES != ds->command_initialized)
   {
@@ -575,12 +573,17 @@ deposit_traits (void *cls,
        (GNUNET_OK !=
         TALER_TESTING_get_trait_age_commitment_proof (coin_cmd,
                                                       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);
     TALER_TESTING_interpreter_fail (ds->is);
     return GNUNET_NO;
   }
+
   {
     struct TALER_TESTING_Trait traits[] = {
       /* First two traits are only available if
@@ -594,6 +597,8 @@ deposit_traits (void *cls,
                                           coin_spent_priv),
       TALER_TESTING_make_trait_age_commitment_proof (0,
                                                      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_contract_terms (ds->contract_terms),
       TALER_TESTING_make_trait_merchant_priv (&ds->merchant_priv),
diff --git a/src/testing/testing_api_cmd_refresh.c 
b/src/testing/testing_api_cmd_refresh.c
index 8782b0b5..3b35a73b 100644
--- a/src/testing/testing_api_cmd_refresh.c
+++ b/src/testing/testing_api_cmd_refresh.c
@@ -75,7 +75,7 @@ struct TALER_TESTING_FreshCoinData
    * applicable.
    */
   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).
@@ -440,8 +440,13 @@ reveal_cb (void *cls,
         return;
       }
       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,
                                  &coin->sig);
@@ -559,7 +564,11 @@ refresh_reveal_cleanup (void *cls,
   }
 
   for (unsigned int j = 0; j < rrs->num_fresh_coins; j++)
+  {
     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->psa);
@@ -1024,12 +1033,12 @@ melt_run (void *cls,
   {
     struct TALER_Amount melt_amount;
     struct TALER_Amount fresh_amount;
-    const struct TALER_AgeCommitmentProof *age_commitment_proof;
-    const struct TALER_AgeCommitmentHash *h_age_commitment;
+    const struct TALER_AgeCommitmentProof *age_commitment_proof = NULL;
+    const struct TALER_AgeCommitmentHash *h_age_commitment = NULL;
     const struct TALER_DenominationSignature *melt_sig;
     const struct TALER_EXCHANGE_DenomPublicKey *melt_denom_pub;
     const struct TALER_TESTING_Command *coin_command;
-    bool age_restricted;
+    bool age_restricted_denom;
 
     if (NULL == (coin_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
        values and withdraw fees of the fresh coins next */
     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++)
     {
       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_amount,
-                                        age_restricted);
+                                        age_restricted_denom);
       if (NULL == fresh_pk)
       {
         GNUNET_break (0);
@@ -1139,13 +1151,20 @@ melt_run (void *cls,
     rms->refresh_data.melt_amount = melt_amount;
     rms->refresh_data.melt_sig = *melt_sig;
     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_len = num_fresh_coins;
 
-    GNUNET_assert (age_restricted ==
+    GNUNET_assert (age_restricted_denom ==
                    (NULL != age_commitment_proof));
+    GNUNET_assert ((NULL == age_commitment_proof) ||
+                   (0 < age_commitment_proof->commitment.num));
 
     rms->rmh = TALER_EXCHANGE_melt (
       TALER_TESTING_interpreter_get_context (is),
@@ -1198,6 +1217,7 @@ melt_cleanup (void *cls,
       TALER_denom_pub_free (&rms->fresh_pks[i].key);
     GNUNET_free (rms->fresh_pks);
   }
+
   GNUNET_free (rms->mbds);
   GNUNET_free (rms->melt_fresh_amounts);
   GNUNET_free (rms);
@@ -1409,7 +1429,7 @@ refresh_reveal_traits (void *cls,
         rrs->fresh_coins[index].age_commitment_proof),
       TALER_TESTING_make_trait_h_age_commitment (
         index,
-        rrs->fresh_coins[index].h_age_commitment),
+        &rrs->fresh_coins[index].h_age_commitment),
       TALER_TESTING_make_trait_denom_pub (
         index,
         rrs->fresh_coins[index].pk),
@@ -1427,6 +1447,7 @@ refresh_reveal_traits (void *cls,
                                                  &rrs->psa[index]),
       TALER_TESTING_trait_end ()
     };
+
     return TALER_TESTING_get_trait (traits,
                                     ret,
                                     trait,
diff --git a/src/testing/testing_api_cmd_run_fakebank.c 
b/src/testing/testing_api_cmd_run_fakebank.c
index f9a6b9b6..3664f160 100644
--- a/src/testing/testing_api_cmd_run_fakebank.c
+++ b/src/testing/testing_api_cmd_run_fakebank.c
@@ -110,6 +110,7 @@ run_fakebank_cleanup (void *cls,
   }
   GNUNET_free (rfs->ba.wire_gateway_url);
   GNUNET_free (rfs->bank_url);
+  GNUNET_free (rfs->currency);
   GNUNET_free (rfs);
 }
 
@@ -194,6 +195,7 @@ TALER_TESTING_cmd_run_fakebank (
                      (unsigned int) fakebank_port,
                      exchange_xtalerbank_account);
     GNUNET_free (exchange_xtalerbank_account);
+    GNUNET_free (exchange_payto_uri);
   }
   rfs->ba.method = TALER_BANK_AUTH_NONE;
   {
diff --git a/src/testing/testing_api_cmd_withdraw.c 
b/src/testing/testing_api_cmd_withdraw.c
index 69a47cb5..2550e55a 100644
--- a/src/testing/testing_api_cmd_withdraw.c
+++ b/src/testing/testing_api_cmd_withdraw.c
@@ -144,10 +144,10 @@ struct WithdrawState
 
   /**
    * 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_AgeCommitmentHash *h_age_commitment;
+  struct TALER_AgeCommitmentProof age_commitment_proof;
+  struct TALER_AgeCommitmentHash h_age_commitment;
 
   /**
    * Reserve history entry that corresponds to this operation.
@@ -438,7 +438,7 @@ withdraw_run (void *cls,
     struct TALER_EXCHANGE_WithdrawCoinInput wci = {
       .pk = ws->pk,
       .ps = &ws->ps,
-      .ach = ws->h_age_commitment
+      .ach = 0 < ws->age ? &ws->h_age_commitment : NULL
     };
     ws->wsh = TALER_EXCHANGE_withdraw (
       TALER_TESTING_interpreter_get_context (is),
@@ -489,16 +489,8 @@ withdraw_cleanup (void *cls,
     TALER_EXCHANGE_destroy_denomination_key (ws->pk);
     ws->pk = NULL;
   }
-  if (NULL != 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;
-  }
+  if (ws->age > 0)
+    TALER_age_commitment_proof_free (&ws->age_commitment_proof);
   GNUNET_free (ws->exchange_url);
   GNUNET_free (ws->reserve_payto_uri);
   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_exchange_url (ws->exchange_url),
     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,
-                                               ws->h_age_commitment),
+                                               0 < ws->age
+                                               ? &ws->h_age_commitment
+                                               : NULL),
     TALER_TESTING_trait_end ()
   };
 
@@ -573,13 +569,9 @@ TALER_TESTING_cmd_withdraw_amount (const char *label,
   ws->age = age;
   if (0 < age)
   {
-    struct TALER_AgeCommitmentProof *acp;
-    struct TALER_AgeCommitmentHash *hac;
     struct GNUNET_HashCode seed;
     struct TALER_AgeMask mask;
 
-    acp = GNUNET_new (struct TALER_AgeCommitmentProof);
-    hac = GNUNET_new (struct TALER_AgeCommitmentHash);
     mask = TALER_extensions_get_age_restriction_mask ();
     GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
                                 &seed,
@@ -590,7 +582,7 @@ TALER_TESTING_cmd_withdraw_amount (const char *label,
           &mask,
           age,
           &seed,
-          acp))
+          &ws->age_commitment_proof))
     {
       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                   "Failed to generate age commitment for age %d at %s\n",
@@ -598,10 +590,8 @@ TALER_TESTING_cmd_withdraw_amount (const char *label,
                   label);
       GNUNET_assert (0);
     }
-    TALER_age_commitment_hash (&acp->commitment,
-                               hac);
-    ws->age_commitment_proof = acp;
-    ws->h_age_commitment = hac;
+    TALER_age_commitment_hash (&ws->age_commitment_proof.commitment,
+                               &ws->h_age_commitment);
   }
 
   ws->reserve_reference = reserve_reference;
diff --git a/src/util/age_restriction.c b/src/util/age_restriction.c
index 6f070229..eec0c834 100644
--- a/src/util/age_restriction.c
+++ b/src/util/age_restriction.c
@@ -464,6 +464,9 @@ void
 TALER_age_proof_free (
   struct TALER_AgeProof *proof)
 {
+  if (NULL == proof)
+    return;
+
   if (NULL != proof->keys)
   {
     GNUNET_CRYPTO_zero_keys (
@@ -479,26 +482,71 @@ TALER_age_proof_free (
 
 void
 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 (
-      cp->proof.keys,
-      sizeof(*cp->proof.keys) * cp->proof.num);
+      acp->proof.keys,
+      sizeof(*acp->proof.keys) * acp->proof.num);
 
-    GNUNET_free (cp->proof.keys);
-    cp->proof.keys = NULL;
+    GNUNET_free (acp->proof.keys);
+    acp->proof.keys = NULL;
   }
 
-  if (NULL != cp->commitment.keys)
+  if (NULL != acp->commitment.keys)
   {
-    GNUNET_free (cp->commitment.keys);
-    cp->commitment.keys = NULL;
+    GNUNET_free (acp->commitment.keys);
+    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
 TALER_JSON_parse_age_groups (const json_t *root,
                              struct TALER_AgeMask *mask)
@@ -571,19 +619,16 @@ TALER_parse_age_group_string (
 }
 
 
-char *
+const char *
 TALER_age_mask_to_string (
   const struct TALER_AgeMask *mask)
 {
+  static char buf[256] = {0};
   uint32_t bits = mask->bits;
   unsigned int n = 0;
-  char *buf = GNUNET_malloc (32 * 3); // max characters possible
   char *pos = buf;
 
-  if (NULL == buf)
-  {
-    return buf;
-  }
+  memset (buf, 0, sizeof(buf));
 
   while (bits != 0)
   {

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]