gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] branch master updated (5bf90c35 -> 3e29bdfb)


From: gnunet
Subject: [taler-exchange] branch master updated (5bf90c35 -> 3e29bdfb)
Date: Mon, 24 Jul 2023 20:30:33 +0200

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

oec pushed a change to branch master
in repository exchange.

    from 5bf90c35 kyc logic with birthdate setting test added
     new e9f7ad37 -gana update
     new 3e29bdfb [age-withdraw] first tests pass

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 contrib/gana                                     |   2 +-
 src/exchange/taler-exchange-httpd_age-withdraw.c | 178 ++++++++++++-----------
 src/exchangedb/exchange_do_age_withdraw.sql      |  34 ++---
 src/exchangedb/pg_do_age_withdraw.c              |  12 +-
 src/exchangedb/pg_do_age_withdraw.h              |   2 +
 src/include/taler_exchange_service.h             |   2 +
 src/include/taler_exchangedb_plugin.h            |   2 +
 src/include/taler_testing_lib.h                  |  36 +++++
 src/lib/exchange_api_age_withdraw.c              |  49 ++++++-
 src/testing/test_exchange_api_age_restriction.c  |  12 ++
 src/testing/testing_api_cmd_age_withdraw.c       |  23 ++-
 src/util/age_restriction.c                       |   8 +-
 12 files changed, 223 insertions(+), 137 deletions(-)

diff --git a/contrib/gana b/contrib/gana
index 86b36917..d04f9909 160000
--- a/contrib/gana
+++ b/contrib/gana
@@ -1 +1 @@
-Subproject commit 86b36917a59cc46961a9c9042b1af75a88545558
+Subproject commit d04f990981fdee8ba1b31d6d61424abbbc03cbc3
diff --git a/src/exchange/taler-exchange-httpd_age-withdraw.c 
b/src/exchange/taler-exchange-httpd_age-withdraw.c
index 106feb01..60bc5fec 100644
--- a/src/exchange/taler-exchange-httpd_age-withdraw.c
+++ b/src/exchange/taler-exchange-httpd_age-withdraw.c
@@ -113,7 +113,7 @@ free_age_withdraw_context_resources (struct 
AgeWithdrawContext *awc)
 static enum GNUNET_GenericReturnValue
 parse_age_withdraw_json (
   struct MHD_Connection *connection,
-  const json_t *j_denoms_h,
+  const json_t *j_denom_hs,
   const json_t *j_blinded_coin_evs,
   struct AgeWithdrawContext *awc,
   MHD_RESULT *mhd_ret)
@@ -135,9 +135,9 @@ parse_age_withdraw_json (
 
   /* Verify JSON-structure consistency */
   {
-    uint32_t num_coins = json_array_size (j_denoms_h);
+    uint32_t num_coins = json_array_size (j_denom_hs);
 
-    if (! json_is_array (j_denoms_h))
+    if (! json_is_array (j_denom_hs))
       error = "denoms_h must be an array";
     else if (! json_is_array (j_blinded_coin_evs))
       error = "coin_evs must be an array";
@@ -168,7 +168,7 @@ parse_age_withdraw_json (
   awc->denom_hs = GNUNET_new_array (awc->num_coins,
                                     struct TALER_DenominationHashP);
 
-  json_array_foreach (j_denoms_h, idx, value) {
+  json_array_foreach (j_denom_hs, idx, value) {
     struct GNUNET_JSON_Specification spec[] = {
       GNUNET_JSON_spec_fixed_auto (NULL, &awc->denom_hs[idx]),
       GNUNET_JSON_spec_end ()
@@ -196,24 +196,17 @@ parse_age_withdraw_json (
 
   /* Parse blinded envelopes. */
   json_array_foreach (j_blinded_coin_evs, idx, value) {
-    const json_t *j_kappa_coin_evs;
-    struct GNUNET_JSON_Specification aspec[] = {
-      GNUNET_JSON_spec_array_const (NULL, &j_kappa_coin_evs),
-      GNUNET_JSON_spec_end ()
-    };
-
-    if (GNUNET_OK !=
-        GNUNET_JSON_parse (value, aspec, NULL, NULL))
+    const json_t *j_kappa_coin_evs = value;
+    if (! json_is_array (j_kappa_coin_evs))
     {
       GNUNET_snprintf (buf,
                        sizeof(buf),
-                       "couldn't parse entry no. %d in array coin_evs",
+                       "enxtry %d in array blinded_coin_evs is not an array",
                        idx + 1);
       error = buf;
       goto EXIT;
     }
-
-    if (TALER_CNC_KAPPA != json_array_size (j_kappa_coin_evs))
+    else if (TALER_CNC_KAPPA != json_array_size (j_kappa_coin_evs))
     {
       GNUNET_snprintf (buf,
                        sizeof(buf),
@@ -223,28 +216,47 @@ parse_age_withdraw_json (
       goto EXIT;
     }
 
-    /* Now parse the individual kappa envelopes */
+    /* Now parse the individual kappa envelopes and calculate the hash of
+     * the commitment along the way. */
     {
       size_t off = idx * TALER_CNC_KAPPA;
-      size_t kappa = 0;
+      unsigned int kappa = 0;
+      enum GNUNET_GenericReturnValue ret;
+      struct GNUNET_HashContext *hash_context;
+
+      hash_context = GNUNET_CRYPTO_hash_context_start ();
 
       json_array_foreach (j_kappa_coin_evs, kappa, value) {
         struct GNUNET_JSON_Specification spec[] = {
-          GNUNET_JSON_spec_fixed_auto (NULL, &awc->coin_evs[off + kappa]),
+          TALER_JSON_spec_blinded_planchet (NULL, &awc->coin_evs[off + kappa]),
           GNUNET_JSON_spec_end ()
         };
-
         if (GNUNET_OK !=
             GNUNET_JSON_parse (value, spec, NULL, NULL))
         {
           GNUNET_snprintf (buf,
                            sizeof(buf),
-                           "couldn't parse array no. %d in coin_evs",
+                           "couldn't parse array no. %d in 
blinded_coin_evs[%d]",
+                           kappa + 1,
                            idx + 1);
           error = buf;
           goto EXIT;
         }
 
+        /* Continue to hash of the coin candidates */
+        {
+          struct TALER_BlindedCoinHashP bch;
+          ret = TALER_coin_ev_hash (&awc->coin_evs[off + kappa],
+                                    &awc->denom_hs[idx],
+                                    &bch);
+
+          GNUNET_assert (GNUNET_OK == ret);
+
+          GNUNET_CRYPTO_hash_context_read (hash_context,
+                                           &bch,
+                                           sizeof(bch));
+        }
+
         /* Check for duplicate planchets
          * FIXME: is this needed?
          */
@@ -258,39 +270,15 @@ parse_age_withdraw_json (
           }
         }
       }
+
+      /* Finally, calculate the h_commitment from all blinded envelopes */
+      GNUNET_CRYPTO_hash_context_finish (hash_context,
+                                         &awc->commitment.h_commitment.hash);
     }
   }; /* json_array_foreach over j_blinded_coin_evs */
 
-  /* We successfully parsed denoms_h and blinded_coins_evs */
   GNUNET_assert (NULL == error);
 
-  /* Finally, calculate the h_commitment from all blinded envelopes */
-  {
-    enum GNUNET_GenericReturnValue ret;
-    struct GNUNET_HashContext *hash_context;
-
-    hash_context = GNUNET_CRYPTO_hash_context_start ();
-
-    for (size_t c = 0;
-         c < TALER_CNC_KAPPA * awc->num_coins;
-         c++)
-    {
-      struct TALER_BlindedCoinHashP bch;
-
-      ret = TALER_coin_ev_hash (&awc->coin_evs[c],
-                                &awc->denom_hs[c],
-                                &bch);
-
-      GNUNET_assert (GNUNET_OK == ret);
-      GNUNET_CRYPTO_hash_context_read (hash_context,
-                                       &bch,
-                                       sizeof(bch));
-    }
-
-    GNUNET_CRYPTO_hash_context_finish (hash_context,
-                                       &awc->commitment.h_commitment.hash);
-  }
-
 
 EXIT:
   if (NULL != error)
@@ -513,7 +501,6 @@ verify_reserve_signature (
   const struct TALER_EXCHANGEDB_AgeWithdraw *commitment,
   enum MHD_Result *mhd_ret)
 {
-
   TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_EDDSA]++;
   if (GNUNET_OK !=
       TALER_wallet_age_withdraw_verify (&commitment->h_commitment,
@@ -741,6 +728,7 @@ age_withdraw_transaction (void *cls,
     bool age_ok = false;
     bool conflict = false;
     uint16_t allowed_maximum_age = 0;
+    uint32_t reserve_birthday = 0;
 
     qs = TEH_plugin->do_age_withdraw (TEH_plugin->cls,
                                       &awc->commitment,
@@ -749,7 +737,29 @@ age_withdraw_transaction (void *cls,
                                       &balance_ok,
                                       &age_ok,
                                       &allowed_maximum_age,
+                                      &reserve_birthday,
                                       &conflict);
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                "XXXXXXX got from do_age_withdraw:"
+                "\n\tqs: %d"
+                "\n\tcommitment: %s"
+                "\n\tmax_age: %d"
+                "\n\tfound: %d"
+                "\n\tbalance_ok: %d"
+                "\n\tage_ok: %d"
+                "\n\tallowed_maximum_age: %d"
+                "\n\treserve_birthday: %d"
+                "\n\tconflict: %d\n",
+                qs,
+                GNUNET_h2s (&awc->commitment.h_commitment.hash),
+                awc->commitment.max_age,
+                found,
+                balance_ok,
+                age_ok,
+                allowed_maximum_age,
+                reserve_birthday,
+                conflict);
+
     if (0 > qs)
     {
       if (GNUNET_DB_STATUS_HARD_ERROR == qs)
@@ -765,18 +775,6 @@ age_withdraw_transaction (void *cls,
                                           NULL);
       return GNUNET_DB_STATUS_HARD_ERROR;
     }
-    else if (! balance_ok)
-    {
-      TEH_plugin->rollback (TEH_plugin->cls);
-
-      *mhd_ret = TEH_RESPONSE_reply_reserve_insufficient_balance (
-        connection,
-        TALER_EC_EXCHANGE_AGE_WITHDRAW_INSUFFICIENT_FUNDS,
-        &awc->commitment.amount_with_fee,
-        &awc->commitment.reserve_pub);
-
-      return GNUNET_DB_STATUS_HARD_ERROR;
-    }
     else if (! age_ok)
     {
       enum TALER_ErrorCode ec =
@@ -785,10 +783,24 @@ age_withdraw_transaction (void *cls,
       *mhd_ret =
         TALER_MHD_REPLY_JSON_PACK (
           connection,
-          TALER_ErrorCode_get_http_status_safe (ec),
+          MHD_HTTP_CONFLICT,
           TALER_MHD_PACK_EC (ec),
           GNUNET_JSON_pack_uint64 ("allowed_maximum_age",
-                                   allowed_maximum_age));
+                                   allowed_maximum_age),
+          GNUNET_JSON_pack_uint64 ("reserve_birthday",
+                                   reserve_birthday));
+
+      return GNUNET_DB_STATUS_HARD_ERROR;
+    }
+    else if (! balance_ok)
+    {
+      TEH_plugin->rollback (TEH_plugin->cls);
+
+      *mhd_ret = TEH_RESPONSE_reply_reserve_insufficient_balance (
+        connection,
+        TALER_EC_EXCHANGE_AGE_WITHDRAW_INSUFFICIENT_FUNDS,
+        &awc->commitment.amount_with_fee,
+        &awc->commitment.reserve_pub);
 
       return GNUNET_DB_STATUS_HARD_ERROR;
     }
@@ -802,6 +814,7 @@ age_withdraw_transaction (void *cls,
       GNUNET_assert (ok);
       return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
     }
+    *mhd_ret = -1;
   }
 
   if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
@@ -842,10 +855,11 @@ sign_and_do_age_withdraw (
   awc->now = GNUNET_TIME_timestamp_get ();
 
   /* Pick the challenge */
-  awc->commitment.noreveal_index =
-    noreveal_index =
-      GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG,
-                                TALER_CNC_KAPPA);
+  noreveal_index =
+    GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG,
+                              TALER_CNC_KAPPA);
+
+  awc->commitment.noreveal_index = noreveal_index;
 
   /* Choose and sign the coins */
   {
@@ -893,21 +907,11 @@ sign_and_do_age_withdraw (
                                 result,
                                 &age_withdraw_transaction,
                                 awc);
-
-  if (GNUNET_OK != ret)
-  {
-    GNUNET_break (0);
-    *result = TALER_MHD_reply_with_error (connection,
-                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
-                                          
TALER_EC_GENERIC_UNEXPECTED_REQUEST_ERROR,
-                                          NULL);
-  }
-
   /* Free resources */
-  awc->commitment.h_coin_evs = NULL;
-  awc->commitment.denom_sigs = NULL;
   for (unsigned int i = 0; i<awc->num_coins; i++)
     TALER_blinded_denom_sig_free (&denom_sigs[i]);
+  awc->commitment.h_coin_evs = NULL;
+  awc->commitment.denom_sigs = NULL;
   return ret;
 }
 
@@ -918,14 +922,14 @@ TEH_handler_age_withdraw (struct TEH_RequestContext *rc,
                           const json_t *root)
 {
   MHD_RESULT mhd_ret;
-  const json_t *j_denoms_h;
-  const json_t *j_blinded_coins_evs;
+  const json_t *j_denom_hs;
+  const json_t *j_blinded_coin_evs;
   struct AgeWithdrawContext awc = {0};
   struct GNUNET_JSON_Specification spec[] = {
-    GNUNET_JSON_spec_array_const ("denoms_h",
-                                  &j_denoms_h),
-    GNUNET_JSON_spec_array_const ("blinded_coins_evs",
-                                  &j_blinded_coins_evs),
+    GNUNET_JSON_spec_array_const ("denom_hs",
+                                  &j_denom_hs),
+    GNUNET_JSON_spec_array_const ("blinded_coin_evs",
+                                  &j_blinded_coin_evs),
     GNUNET_JSON_spec_uint16 ("max_age",
                              &awc.commitment.max_age),
     GNUNET_JSON_spec_fixed_auto ("reserve_sig",
@@ -957,8 +961,8 @@ TEH_handler_age_withdraw (struct TEH_RequestContext *rc,
     /* Parse denoms_h and blinded_coins_evs, partially fill awc */
     if (GNUNET_OK !=
         parse_age_withdraw_json (rc->connection,
-                                 j_denoms_h,
-                                 j_blinded_coins_evs,
+                                 j_denom_hs,
+                                 j_blinded_coin_evs,
                                  &awc,
                                  &mhd_ret))
       break;
diff --git a/src/exchangedb/exchange_do_age_withdraw.sql 
b/src/exchangedb/exchange_do_age_withdraw.sql
index d6ae118a..2230d4bf 100644
--- a/src/exchangedb/exchange_do_age_withdraw.sql
+++ b/src/exchangedb/exchange_do_age_withdraw.sql
@@ -32,6 +32,7 @@ CREATE OR REPLACE FUNCTION exchange_do_age_withdraw(
   OUT balance_ok BOOLEAN,
   OUT age_ok BOOLEAN,
   OUT required_age INT2, -- in years ϵ [0,1..)
+  OUT reserve_birthday INT4,
   OUT conflict BOOLEAN)
 LANGUAGE plpgsql
 AS $$
@@ -39,7 +40,6 @@ DECLARE
   reserve_gc INT8;
   reserve_val INT8;
   reserve_frac INT4;
-  reserve_birthday INT4;
   not_before date;
   earliest_date date;
 BEGIN
@@ -64,23 +64,20 @@ SELECT
 
 IF NOT FOUND
 THEN
-  -- reserve unknown
   reserve_found=FALSE;
-  balance_ok=FALSE;
-  age_ok=FALSE;
-  required_age=0;
+  age_ok = FALSE;
+  required_age=-1;
   conflict=FALSE;
+  balance_ok=FALSE;
   RETURN;
 END IF;
 
+reserve_found = TRUE;
+conflict=FALSE;  -- not really yet determined
 
 -- Check age requirements
-IF ((maximum_age_committed = 0) OR (reserve_birthday = 0))
+IF (reserve_birthday <> 0)
 THEN
-  -- No commitment to a non-zero age was provided or the reserve is marked as
-  -- having no age restriction. We can simply pass.
-  age_ok = OK;
-ELSE 
   not_before=date '1970-01-01' + reserve_birthday;
   earliest_date = current_date - make_interval(maximum_age_committed);
   --
@@ -95,14 +92,18 @@ ELSE
   --
   IF (earliest_date < not_before)
   THEN
-    reserve_found = TRUE;
-    balance_ok = FALSE;
+    required_age = extract(year from age(current_date, not_before));
     age_ok = FALSE;
-    required_age = extract(year from age(not_before, current_date)) + 1;
+    balance_ok=TRUE; -- NOT REALLY
     RETURN;
   END IF;
 END IF;
 
+age_ok = TRUE;
+required_age=0;
+
+
+
 -- Check reserve balance is sufficient.
 IF (reserve_val > amount_val)
 THEN
@@ -125,6 +126,8 @@ ELSE
   END IF;
 END IF;
 
+balance_ok=TRUE;
+
 -- Calculate new expiration dates.
 min_reserve_gc=GREATEST(min_reserve_gc,reserve_gc);
 
@@ -136,9 +139,6 @@ UPDATE reserves SET
 WHERE
   reserves.reserve_pub=rpub;
 
-reserve_found=TRUE;
-balance_ok=TRUE;
-
 -- Write the commitment into the age-withdraw table
 INSERT INTO exchange.age_withdraw
   (h_commitment
@@ -146,7 +146,7 @@ INSERT INTO exchange.age_withdraw
   ,reserve_pub
   ,reserve_sig
   ,noreveal_index
-  ,denomination_serials
+  ,denom_serials
   ,h_blind_evs
   ,denom_sigs)
 VALUES
diff --git a/src/exchangedb/pg_do_age_withdraw.c 
b/src/exchangedb/pg_do_age_withdraw.c
index 8a93ef8d..c79b2b3d 100644
--- a/src/exchangedb/pg_do_age_withdraw.c
+++ b/src/exchangedb/pg_do_age_withdraw.c
@@ -38,8 +38,8 @@ TEH_PG_do_age_withdraw (
   bool *balance_ok,
   bool *age_ok,
   uint16_t *required_age,
-  bool *conflict,
-  uint64_t *ruuid)
+  uint32_t *reserve_birthday,
+  bool *conflict)
 {
   struct PostgresClosure *pg = cls;
   struct GNUNET_TIME_Timestamp gc;
@@ -72,10 +72,10 @@ TEH_PG_do_age_withdraw (
                                 age_ok),
     GNUNET_PQ_result_spec_uint16 ("required_age",
                                   required_age),
+    GNUNET_PQ_result_spec_uint32 ("reserve_birthday",
+                                  reserve_birthday),
     GNUNET_PQ_result_spec_bool ("conflict",
                                 conflict),
-    GNUNET_PQ_result_spec_uint64 ("ruuid",
-                                  ruuid),
     GNUNET_PQ_result_spec_end
   };
 
@@ -93,9 +93,9 @@ TEH_PG_do_age_withdraw (
            ",balance_ok"
            ",age_ok"
            ",required_age"
+           ",reserve_birthday"
            ",conflict"
-           ",ruuid"
-           " FROM exchange_do_batch_withdraw"
+           " FROM exchange_do_age_withdraw"
            " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12);");
   return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                    "call_age_withdraw",
diff --git a/src/exchangedb/pg_do_age_withdraw.h 
b/src/exchangedb/pg_do_age_withdraw.h
index 8f42bfb5..71376022 100644
--- a/src/exchangedb/pg_do_age_withdraw.h
+++ b/src/exchangedb/pg_do_age_withdraw.h
@@ -36,6 +36,7 @@
  * @param[out] balance_ok set to true if the balance was sufficient
  * @param[out] age_ok set to true if no age requirements are present on the 
reserve
  * @param[out] required_age if @e age_ok is false, set to the maximum allowed 
age when withdrawing from this reserve
+ * @param[out] reserve_birthday if @e age_ok is false, set to the birthday of 
the reserve
  * @param[out] conflict set to true if there already is an entry in the 
database for the given pair (h_commitment, reserve_pub)
  * @return query execution status
  */
@@ -48,6 +49,7 @@ TEH_PG_do_age_withdraw (
   bool *balance_ok,
   bool *age_ok,
   uint16_t *required_age,
+  uint32_t *reserve_birthday,
   bool *conflict);
 
 #endif
diff --git a/src/include/taler_exchange_service.h 
b/src/include/taler_exchange_service.h
index 7bd1b324..e8d78916 100644
--- a/src/include/taler_exchange_service.h
+++ b/src/include/taler_exchange_service.h
@@ -2966,6 +2966,7 @@ struct TALER_EXCHANGE_AgeWithdrawBlindedHandle;
  * @param curl_ctx The curl context to use
  * @param exchange_url The base-URL of the exchange
  * @param keys The /keys material from the exchange
+ * @param max_age The maximum age that the coins are committed to.
  * @param num_input number of entries in the @a blinded_input array
  * @param blinded_input array of planchet details of the planchet to withdraw
  * @param reserve_priv private key of the reserve to withdraw from
@@ -2981,6 +2982,7 @@ TALER_EXCHANGE_age_withdraw_blinded (
   struct TALER_EXCHANGE_Keys *keys,
   const char *exchange_url,
   const struct TALER_ReservePrivateKeyP *reserve_priv,
+  uint8_t max_age,
   unsigned int num_input,
   const struct TALER_EXCHANGE_AgeWithdrawBlindedInput blinded_input[static
                                                                     num_input],
diff --git a/src/include/taler_exchangedb_plugin.h 
b/src/include/taler_exchangedb_plugin.h
index c4b894e2..f5fdd7f1 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -3863,6 +3863,7 @@ struct TALER_EXCHANGEDB_Plugin
    * @param[out] balance_ok set to true if the balance was sufficient
    * @param[out] age_ok set to true if age requirements were met
    * @param[out] allowed_maximum_age if @e age_ok is FALSE, this is set to the 
allowed maximum age
+   * @param[out] reserve_birthday if @e age_ok is FALSE, this is set to the 
reserve's birthday
    * @return query execution status
    */
   enum GNUNET_DB_QueryStatus
@@ -3874,6 +3875,7 @@ struct TALER_EXCHANGEDB_Plugin
     bool *balance_ok,
     bool *age_ok,
     uint16_t *allowed_maximum_age,
+    uint32_t *reserve_birthday,
     bool *conflict);
 
   /**
diff --git a/src/include/taler_testing_lib.h b/src/include/taler_testing_lib.h
index c2893769..a514ad2d 100644
--- a/src/include/taler_testing_lib.h
+++ b/src/include/taler_testing_lib.h
@@ -1130,6 +1130,42 @@ TALER_TESTING_cmd_batch_withdraw (const char *label,
                                   const char *amount,
                                   ...);
 
+/**
+ * Create an age-withdraw command, letting the caller specify
+ * the maximum agend and desired amounts as string.  Takes a variable,
+ * non-empty list of the denomination amounts via VARARGS, similar to
+ * #TALER_TESTING_cmd_withdraw_amount(), just using a batch withdraw.
+ *
+ * @param label command label.
+ * @param reserve_reference command providing us with a reserve to withdraw 
from
+ * @param max_age maximum allowed age, same for each coin
+ * @param expected_response_code which HTTP response code
+ *        we expect from the exchange.
+ * @param amount how much we withdraw for the first coin
+ * @param ... NULL-terminated list of additional amounts to withdraw (one per 
coin)
+ * @return the withdraw command to be executed by the interpreter.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_age_withdraw (const char *label,
+                                const char *reserve_reference,
+                                uint8_t max_age,
+                                unsigned int expected_response_code,
+                                const char *amount,
+                                ...);
+
+/**
+ * Create a "age-withdraw reveal" command.
+ *
+ * @param label command label.
+ * @param age_withdraw_reference reference to a "age-withdraw" command.
+ * @param expected_response_code expected HTTP response code.
+ * @return the command.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_age_withdraw_reveal (
+  const char *label,
+  const char *age_withdraw_reference,
+  unsigned int expected_response_code);
 
 /**
  * Create a withdraw command, letting the caller specify
diff --git a/src/lib/exchange_api_age_withdraw.c 
b/src/lib/exchange_api_age_withdraw.c
index c68fe67d..bd84dcb3 100644
--- a/src/lib/exchange_api_age_withdraw.c
+++ b/src/lib/exchange_api_age_withdraw.c
@@ -29,12 +29,14 @@
 #include <gnunet/gnunet_curl_lib.h>
 #include <sys/wait.h>
 #include "taler_curl_lib.h"
+#include "taler_error_codes.h"
 #include "taler_json_lib.h"
 #include "taler_exchange_service.h"
 #include "exchange_api_common.h"
 #include "exchange_api_handle.h"
 #include "taler_signatures.h"
 #include "exchange_api_curl_defaults.h"
+#include "taler_util.h"
 
 /**
  * A CoinCandidate is populated from a master secret
@@ -315,12 +317,13 @@ reserve_age_withdraw_ok (
   };
   struct TALER_ExchangeSignatureP exchange_sig;
   struct GNUNET_JSON_Specification spec[] = {
-    GNUNET_JSON_spec_uint8 ("noreaveal_index",
+    GNUNET_JSON_spec_uint8 ("noreveal_index",
                             &response.details.ok.noreveal_index),
     GNUNET_JSON_spec_fixed_auto ("exchange_sig",
                                  &exchange_sig),
     GNUNET_JSON_spec_fixed_auto ("exchange_pub",
-                                 &response.details.ok.exchange_pub)
+                                 &response.details.ok.exchange_pub),
+    GNUNET_JSON_spec_end ()
   };
 
   if (GNUNET_OK!=
@@ -538,6 +541,14 @@ handle_reserve_age_withdraw_blinded_finished (
     awbr.hr.hint = TALER_JSON_get_error_hint (j_response);
     break;
   case MHD_HTTP_CONFLICT:
+    /* The age requirements might not have been met */
+    awbr.hr.ec = TALER_JSON_get_error_code (j_response);
+    if (TALER_EC_EXCHANGE_AGE_WITHDRAW_MAXIMUM_AGE_TOO_LARGE == awbr.hr.ec)
+    {
+      awbr.hr.hint = TALER_JSON_get_error_hint (j_response);
+      break;
+    }
+
     /* The exchange says that the reserve has insufficient funds;
        check the signatures in the history... */
     if (GNUNET_OK !=
@@ -611,6 +622,9 @@ perform_protocol (
   json_t *j_request_body = NULL;
   CURL *curlh = NULL;
 
+  GNUNET_assert (0 < awbh->num_input);
+  awbh->age_mask = awbh->blinded_input[0].denom_pub->key.age_mask;
+
   FAIL_IF (GNUNET_OK !=
            TALER_amount_set_zero (awbh->keys->currency,
                                   &awbh->amount_with_fee));
@@ -649,12 +663,17 @@ perform_protocol (
   {
     /* Build the denomination array */
     {
-      const struct TALER_EXCHANGE_DenomPublicKey *denom =
+      const struct TALER_EXCHANGE_DenomPublicKey *denom_pub =
         awbh->blinded_input[i].denom_pub;
-      json_t *jdenom = GNUNET_JSON_PACK (
-        TALER_JSON_pack_denom_pub (NULL,
-                                   &denom->key));
+      const struct TALER_DenominationHashP *denom_h = &denom_pub->h_key;
+      json_t *jdenom;
+
+      /* The mask must be the same for all coins */
+      FAIL_IF (awbh->age_mask.bits != denom_pub->key.age_mask.bits);
 
+      jdenom = GNUNET_JSON_PACK (
+        GNUNET_JSON_pack_data_auto (NULL,
+                                    denom_h));
       FAIL_IF (NULL == jdenom);
       FAIL_IF (0 < json_array_append_new (j_denoms,
                                           jdenom));
@@ -686,6 +705,9 @@ perform_protocol (
                                            &bch,
                                            sizeof(bch));
         }
+
+        FAIL_IF (0 < json_array_append_new (j_array_candidates,
+                                            j_can));
       }
     }
   }
@@ -702,9 +724,17 @@ perform_protocol (
                                   awbh->reserve_priv,
                                   &awbh->reserve_sig);
 
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_wallet_age_withdraw_verify (&awbh->h_commitment,
+                                                   &awbh->amount_with_fee,
+                                                   &awbh->age_mask,
+                                                   awbh->max_age,
+                                                   &awbh->reserve_pub,
+                                                   &awbh->reserve_sig));
+
   /* Initiate the POST-request */
   j_request_body = GNUNET_JSON_PACK (
-    GNUNET_JSON_pack_array_steal ("denoms_h", j_denoms),
+    GNUNET_JSON_pack_array_steal ("denom_hs", j_denoms),
     GNUNET_JSON_pack_array_steal ("blinded_coin_evs", j_array_candidates),
     GNUNET_JSON_pack_uint64 ("max_age", awbh->max_age),
     GNUNET_JSON_pack_data_auto ("reserve_sig", &awbh->reserve_sig));
@@ -813,6 +843,7 @@ call_age_withdraw_blinded (
       awh->keys,
       awh->exchange_url,
       awh->reserve_priv,
+      awh->max_age,
       awh->num_coins,
       blinded_input,
       copy_results,
@@ -1064,7 +1095,7 @@ prepare_coins (
               &cd->denom_pub,
               &planchet->blinded_planchet.details.cs_blinded_planchet.nonce,
               &csr_withdraw_done,
-              &cls);
+              cls);
           FAIL_IF (NULL == cls->csr_withdraw_handle);
 
           awh->csr.pending++;
@@ -1163,6 +1194,7 @@ TALER_EXCHANGE_age_withdraw_blinded (
   struct TALER_EXCHANGE_Keys *keys,
   const char *exchange_url,
   const struct TALER_ReservePrivateKeyP *reserve_priv,
+  uint8_t max_age,
   unsigned int num_input,
   const struct TALER_EXCHANGE_AgeWithdrawBlindedInput blinded_input[static
                                                                     num_input],
@@ -1179,6 +1211,7 @@ TALER_EXCHANGE_age_withdraw_blinded (
   awbh->reserve_priv = reserve_priv;
   awbh->callback = res_cb;
   awbh->callback_cls = res_cb_cls;
+  awbh->max_age = max_age;
 
   GNUNET_CRYPTO_eddsa_key_get_public (&awbh->reserve_priv->eddsa_priv,
                                       &awbh->reserve_pub.eddsa_pub);
diff --git a/src/testing/test_exchange_api_age_restriction.c 
b/src/testing/test_exchange_api_age_restriction.c
index 93bd28bf..b3f7357f 100644
--- a/src/testing/test_exchange_api_age_restriction.c
+++ b/src/testing/test_exchange_api_age_restriction.c
@@ -284,6 +284,18 @@ run (void *cls,
                                        "EUR:10",
                                        0, /* age restriction off */
                                        MHD_HTTP_CONFLICT),
+    TALER_TESTING_cmd_age_withdraw ("age-withdraw-coin-1-too-low",
+                                    "create-reserve-kyc-1",
+                                    18, /* Too high */
+                                    MHD_HTTP_CONFLICT,
+                                    "EUR:10",
+                                    NULL),
+    TALER_TESTING_cmd_age_withdraw ("age-withdraw-coin-1",
+                                    "create-reserve-kyc-1",
+                                    8,
+                                    MHD_HTTP_OK,
+                                    "EUR:10",
+                                    NULL),
     TALER_TESTING_cmd_end (),
   };
 
diff --git a/src/testing/testing_api_cmd_age_withdraw.c 
b/src/testing/testing_api_cmd_age_withdraw.c
index ea3249c0..9b7bfd20 100644
--- a/src/testing/testing_api_cmd_age_withdraw.c
+++ b/src/testing/testing_api_cmd_age_withdraw.c
@@ -209,21 +209,15 @@ age_withdraw_cb (
     break;
   case MHD_HTTP_CONFLICT:
     /* TODO[oec]: Add this to the response-type and handle it here */
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                "Age withdraw test command does not YET support status code 
%u\n",
-                response->hr.http_status);
     break;
   case MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS:
-    /* TODO[oec]: Add this to response-type and handle it here  */
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                "Age withdraw test command does not YET support status code 
%u\n",
-                response->hr.http_status);
-    break;
   default:
     /* Unsupported status code (by test harness) */
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                "Age withdraw test command does not support status code %u\n",
-                response->hr.http_status);
+                "test command for age-withdraw not support status code %u, 
body:\n"
+                ">>%s<<\n",
+                response->hr.http_status,
+                json_dumps (response->hr.reply, JSON_INDENT (2)));
     GNUNET_break (0);
     break;
   }
@@ -366,12 +360,13 @@ age_withdraw_cleanup (
     struct TALER_EXCHANGE_AgeWithdrawCoinInput *in = &aws->coin_inputs[n];
     struct CoinOutputState *out = &aws->coin_outputs[n];
 
-    if (NULL != in->denom_pub)
+    if (NULL != in && NULL != in->denom_pub)
     {
       TALER_EXCHANGE_destroy_denomination_key (in->denom_pub);
       in->denom_pub = NULL;
     }
-    TALER_age_commitment_proof_free (&out->details.age_commitment_proof);
+    if (NULL != out)
+      TALER_age_commitment_proof_free (&out->details.age_commitment_proof);
   }
   GNUNET_free (aws->coin_inputs);
   GNUNET_free (aws->coin_outputs);
@@ -490,10 +485,10 @@ TALER_TESTING_cmd_age_withdraw (const char *label,
                   label);
       GNUNET_assert (0);
     }
+    /* move on to next vararg! */
+    amount = va_arg (ap, const char *);
   }
 
-  /* move on to next vararg! */
-  amount = va_arg (ap, const char *);
   GNUNET_assert (NULL == amount);
   va_end (ap);
 
diff --git a/src/util/age_restriction.c b/src/util/age_restriction.c
index eec0c834..d8c6e4da 100644
--- a/src/util/age_restriction.c
+++ b/src/util/age_restriction.c
@@ -32,10 +32,10 @@ GNUNET_CRYPTO_Edx25519PublicKey
 GNUNET_CRYPTO_EcdsaPublicKey
 #endif
 TALER_age_commitment_base_public_key = {
-  .q_y = { 0x6f, 0xe5, 0x87, 0x9a, 0x3d, 0xa9, 0x44, 0x20,
-           0x80, 0xbd, 0x6a, 0xb9, 0x44, 0x56, 0x91, 0x19,
-           0xaf, 0xb4, 0xc8, 0x7b, 0x89, 0xce, 0x23, 0x17,
-           0x97, 0x20, 0x5c, 0xbb, 0x9c, 0xd7, 0xcc, 0xd9},
+  .q_y = { 0x64, 0x41, 0xb9, 0xbd, 0xbf, 0x14, 0x39, 0x8e,
+           0x46, 0xeb, 0x5c, 0x1d, 0x34, 0xd3, 0x9b, 0x2f,
+           0x9b, 0x7d, 0xc8, 0x18, 0xeb, 0x9c, 0x09, 0xfb,
+           0x43, 0xad, 0x16, 0x64, 0xbc, 0x18, 0x49, 0xb5},
 };
 
 void

-- 
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]