gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] branch master updated (bdd81674 -> 8638446f)


From: gnunet
Subject: [taler-exchange] branch master updated (bdd81674 -> 8638446f)
Date: Thu, 23 Jun 2022 18:30:20 +0200

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

oec pushed a change to branch master
in repository exchange.

    from bdd81674 -fix versions
     new c165ef31 first steps towards new /keys response: grouped denominations 
added
     new 09c9054b -fix initialization issue
     new debc6ed9 -fix initialization issue
     new a63e706c -fix build issues
     new ca61b641 -make pg a recommendation, include version
     new 8638446f -fix versions

The 6 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:
 src/exchange/taler-exchange-httpd_keys.c | 321 +++++++++++++++++++++++--------
 1 file changed, 241 insertions(+), 80 deletions(-)

diff --git a/src/exchange/taler-exchange-httpd_keys.c 
b/src/exchange/taler-exchange-httpd_keys.c
index b3f0eb48..45bed1a1 100644
--- a/src/exchange/taler-exchange-httpd_keys.c
+++ b/src/exchange/taler-exchange-httpd_keys.c
@@ -283,7 +283,6 @@ struct SigningKey
 
 };
 
-
 struct TEH_KeyStateHandle
 {
 
@@ -404,7 +403,6 @@ struct SuspendedKeysRequests
   struct GNUNET_TIME_Absolute timeout;
 };
 
-
 /**
  * Stores the latest generation of our key state.
  */
@@ -1353,7 +1351,7 @@ denomination_info_cb (
   dk->meta = *meta;
   dk->master_sig = *master_sig;
   dk->recoup_possible = recoup_possible;
-  dk->denom_pub.age_mask = meta->age_mask;
+  dk->denom_pub.age_mask = meta->age_mask; /* FIXME-oec: age_mask -> 
reserved_field */
 
   GNUNET_assert (
     GNUNET_OK ==
@@ -1361,6 +1359,7 @@ denomination_info_cb (
                                        &dk->h_denom_pub.hash,
                                        dk,
                                        
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
+
 }
 
 
@@ -1727,12 +1726,12 @@ setup_general_response_headers (struct 
TEH_KeyStateHandle *ksh,
  * @a recoup and @a denoms.
  *
  * @param[in,out] ksh key state handle we build @a krd for
- * @param[in] denom_keys_hash hash over all the denominatoin keys in @a denoms 
and age_restricted_denoms
+ * @param[in] denom_keys_hash hash over all the denominatoin keys in @a denoms
  * @param last_cpd timestamp to use
  * @param signkeys list of sign keys to return
  * @param recoup list of revoked keys to return
  * @param denoms list of denominations to return
- * @param age_restricted_denoms list of age restricted denominations to 
return, can be NULL
+ * @param grouped_denominations list of grouped denominations to return
  * @return #GNUNET_OK on success
  */
 static enum GNUNET_GenericReturnValue
@@ -1742,7 +1741,7 @@ create_krd (struct TEH_KeyStateHandle *ksh,
             json_t *signkeys,
             json_t *recoup,
             json_t *denoms,
-            json_t *age_restricted_denoms)
+            json_t *grouped_denominations)
 {
   struct KeysResponseData krd;
   struct TALER_ExchangePublicKeyP exchange_pub;
@@ -1753,6 +1752,7 @@ create_krd (struct TEH_KeyStateHandle *ksh,
   GNUNET_assert (NULL != signkeys);
   GNUNET_assert (NULL != recoup);
   GNUNET_assert (NULL != denoms);
+  GNUNET_assert (NULL != grouped_denominations);
   GNUNET_assert (NULL != ksh->auditors);
   GNUNET_assert (NULL != TEH_currency);
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@@ -1778,6 +1778,7 @@ create_krd (struct TEH_KeyStateHandle *ksh,
       return GNUNET_SYSERR;
     }
   }
+
   {
     const struct SigningKey *sk;
 
@@ -1803,6 +1804,8 @@ create_krd (struct TEH_KeyStateHandle *ksh,
                                    recoup),
     GNUNET_JSON_pack_array_incref ("denoms",
                                    denoms),
+    GNUNET_JSON_pack_array_incref ("denominations",
+                                   grouped_denominations),
     GNUNET_JSON_pack_array_incref ("auditors",
                                    ksh->auditors),
     GNUNET_JSON_pack_array_incref ("global_fees",
@@ -1833,7 +1836,6 @@ create_krd (struct TEH_KeyStateHandle *ksh,
   {
     json_t *extensions = json_object ();
     bool has_extensions = false;
-    bool age_restriction_enabled = false;
 
     /* Fill in the configurations of the enabled extensions */
     for (const struct TALER_Extension *extension = TALER_extensions_get_head 
();
@@ -1851,8 +1853,6 @@ create_krd (struct TEH_KeyStateHandle *ksh,
 
       /* flag our findings so far */
       has_extensions = true;
-      age_restriction_enabled = (extension->type ==
-                                 TALER_Extension_AgeRestriction);
 
       GNUNET_assert (NULL != extension->config_json);
 
@@ -1901,20 +1901,6 @@ create_krd (struct TEH_KeyStateHandle *ksh,
     {
       json_decref (extensions);
     }
-
-    // Special case for age restrictions: if enabled, provide the list of
-    // age-restricted denominations.
-    if (age_restriction_enabled &&
-        NULL != age_restricted_denoms)
-    {
-      GNUNET_assert (
-        0 ==
-        json_object_set (
-          keys,
-          "age_restricted_denoms",
-          age_restricted_denoms));
-    }
-
   }
 
 
@@ -2010,12 +1996,10 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
   json_t *recoup;
   struct SignKeyCtx sctx;
   json_t *denoms = NULL;
-  json_t *age_restricted_denoms = NULL;
+  json_t *grouped_denominations = NULL;
   struct GNUNET_TIME_Timestamp last_cpd;
   struct GNUNET_CONTAINER_Heap *heap;
   struct GNUNET_HashContext *hash_context = NULL;
-  struct GNUNET_HashContext *hash_context_restricted = NULL;
-  bool have_age_restricted_denoms = false;
 
   sctx.signkeys = json_array ();
   GNUNET_assert (NULL != sctx.signkeys);
@@ -2045,20 +2029,25 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
   GNUNET_assert (NULL != denoms);
   hash_context = GNUNET_CRYPTO_hash_context_start ();
 
-  /* If age restriction is enabled, initialize the array of age restricted
-   denoms  and prepare a hash for them, separate from the others.  We will join
-   those hashes afterwards.*/
-  if (0)
-  {
-    age_restricted_denoms = json_array ();
-    GNUNET_assert (NULL != age_restricted_denoms);
-    hash_context_restricted = GNUNET_CRYPTO_hash_context_start ();
-  }
+  grouped_denominations = json_array ();
+  GNUNET_assert (NULL != grouped_denominations);
 
   last_cpd = GNUNET_TIME_UNIT_ZERO_TS;
 
   {
     struct TEH_DenominationKey *dk;
+    struct GNUNET_CONTAINER_MultiHashMap *denominations_by_group;
+
+    denominations_by_group =
+      GNUNET_CONTAINER_multihashmap_create (1024,
+                                            GNUNET_NO /* NO, because keys are 
only on the stack */);
+
+    /* groupData is the value we store for each group meta-data */
+    struct groupData
+    {
+      json_t *json;   /* The json blob with the group meta-data and list of 
denominations */
+      struct GNUNET_HashContext *hash_context;   /* hash over all 
denominations in that group */
+    };
 
     /* heap = min heap, sorted by start time */
     while (NULL != (dk = GNUNET_CONTAINER_heap_remove_root (heap)))
@@ -2068,12 +2057,12 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
                                      dk->meta.start) &&
           (! GNUNET_TIME_absolute_is_zero (last_cpd.abs_time)) )
       {
-        struct GNUNET_HashCode hc;
-
-        /* FIXME-oec: Do we need to take hash_context_restricted into account
-         * in this if-branch!?  Current tests suggests: no, (they don't fail).
-         * But something seems to be odd about only finishing hash_context.
+        /*
+         * This is not the first entry in the heap (because last_cpd !=
+         * GNUNET_TIME_UNIT_ZERO_TS) and the previous entry had a different
+         * start time.  Therefore, we create an entry in the ksh.
          */
+        struct GNUNET_HashCode hc;
 
         GNUNET_CRYPTO_hash_context_finish (
           GNUNET_CRYPTO_hash_context_copy (hash_context),
@@ -2085,7 +2074,7 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
                         sctx.signkeys,
                         recoup,
                         denoms,
-                        age_restricted_denoms))
+                        grouped_denominations))
         {
           GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                       "Failed to generate key response data for %s\n",
@@ -2096,8 +2085,7 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
             /* intentionally empty */;
           GNUNET_CONTAINER_heap_destroy (heap);
           json_decref (denoms);
-          if (NULL != age_restricted_denoms)
-            json_decref (age_restricted_denoms);
+          json_decref (grouped_denominations);
           json_decref (sctx.signkeys);
           json_decref (recoup);
           return GNUNET_SYSERR;
@@ -2108,9 +2096,6 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
 
       {
         json_t *denom;
-        json_t *array;
-        struct GNUNET_HashContext *hc;
-
 
         denom =
           GNUNET_JSON_PACK (
@@ -2131,33 +2116,222 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
             TALER_JSON_PACK_DENOM_FEES ("fee",
                                         &dk->meta.fees));
 
-        /* Put the denom into the correct array depending on the settings and
-         * the properties of the denomination.  Also, we build up the right
-         * hash for the corresponding array. */
-        if (0 &&
-            (0 != dk->denom_pub.age_mask.bits))
+        GNUNET_CRYPTO_hash_context_read (hash_context,
+                                         &dk->h_denom_pub,
+                                         sizeof (struct GNUNET_HashCode));
+
+        GNUNET_assert (
+          0 ==
+          json_array_append_new (
+            denoms,
+            denom));
+
+      }
+
+      /**
+       * Group the denominations by {cipher, value, fees, age_mask}.
+       *
+       * For each group we save the group meta-data and the list of
+       * denominations in this group as a json-blob in the multihashmap
+       * denominations_by_group.
+       **/
+
+      {
+        static const char *denoms_key = "denoms";
+        struct groupData *group;
+        json_t *list;
+        json_t *entry;
+        struct GNUNET_HashCode key;
+
+        /* Find the group/JSON-blob for the key */
+        struct
+        {
+          enum TALER_DenominationCipher cipher;
+          struct TALER_AgeMask age_mask;
+          struct TALER_Amount value;
+          struct TALER_DenomFeeSet fees;
+        } meta = {
+          .cipher = dk->denom_pub.cipher,
+          .value = dk->meta.value,
+          .fees = dk->meta.fees,
+          .age_mask = dk->meta.age_mask,
+        };
+
+        GNUNET_CRYPTO_hash (&meta, sizeof(meta), &key);
+
+        group = (struct groupData *) GNUNET_CONTAINER_multihashmap_get (
+          denominations_by_group,
+          &key);
+
+        if (NULL == group)
         {
-          have_age_restricted_denoms = true;
-          array = age_restricted_denoms;
-          hc = hash_context_restricted;
+          /*
+           * There is no group for this meta-data yet, so let's create a new
+           * group entry.
+           */
+
+          bool age_restricted = meta.age_mask.bits != 0;
+          char *cipher;
+
+          group = GNUNET_new (struct groupData);
+          group->hash_context = GNUNET_CRYPTO_hash_context_start ();
+
+          switch (meta.cipher)
+          {
+          case TALER_DENOMINATION_RSA:
+            cipher = age_restricted ? "RSA+age_restriction": "RSA";
+            break;
+          case TALER_DENOMINATION_CS:
+            cipher = age_restricted ? "CS+age_restriction": "CS";
+            break;
+          default:
+            GNUNET_assert (false);
+          }
+
+          group->json = GNUNET_JSON_PACK (
+            GNUNET_JSON_pack_string ("cipher", cipher),
+            TALER_JSON_PACK_DENOM_FEES ("fee", &meta.fees),
+            TALER_JSON_pack_amount ("value", &meta.value));
+          GNUNET_assert (NULL != group->json);
+
+          if (age_restricted)
+          {
+            GNUNET_assert (0 ==
+                           json_object_set (group->json,
+                                            "age_mask",
+                                            json_integer 
(meta.age_mask.bits)));
+          }
+
+          /* Create a new array for the denominations in this group */
+          list = json_array ();
+          GNUNET_assert (NULL != list);
+          GNUNET_assert (0 ==
+                         json_object_set (group->json, denoms_key, list));
+
+          GNUNET_assert (
+            GNUNET_OK ==
+            GNUNET_CONTAINER_multihashmap_put (denominations_by_group,
+                                               &key,
+                                               group,
+                                               
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
         }
-        else
+
+        /*
+         * Now that we have found/created the right group, add the denomination
+         * to the list
+         */
         {
-          array = denoms;
-          hc = hash_context;
+          struct GNUNET_JSON_PackSpec key_spec;
+
+          switch (meta.cipher)
+          {
+          case TALER_DENOMINATION_RSA:
+            key_spec =
+              GNUNET_JSON_pack_rsa_public_key ("rsa_pub",
+                                               dk->denom_pub.details.
+                                               rsa_public_key);
+            break;
+          case TALER_DENOMINATION_CS:
+            key_spec =
+              GNUNET_JSON_pack_data_varsize ("cs_pub",
+                                             &dk->denom_pub.details.
+                                             cs_public_key,
+                                             sizeof (dk->denom_pub.details.
+                                                     cs_public_key));
+            break;
+          default:
+            GNUNET_assert (false);
+          }
+
+          entry = GNUNET_JSON_PACK (
+            GNUNET_JSON_pack_data_auto ("master_sig",
+                                        &dk->master_sig),
+            GNUNET_JSON_pack_timestamp ("stamp_start",
+                                        dk->meta.start),
+            GNUNET_JSON_pack_timestamp ("stamp_expire_withdraw",
+                                        dk->meta.expire_withdraw),
+            GNUNET_JSON_pack_timestamp ("stamp_expire_deposit",
+                                        dk->meta.expire_deposit),
+            GNUNET_JSON_pack_timestamp ("stamp_expire_legal",
+                                        dk->meta.expire_legal),
+            key_spec
+            );
+          GNUNET_assert (NULL != entry);
         }
 
-        GNUNET_CRYPTO_hash_context_read (hc,
+        /*
+         * Build up the running hash of all denominations in this group
+         * TODO: FIXME-oec: this is cipher and age_restriction dependend?!
+         */
+        GNUNET_CRYPTO_hash_context_read (group->hash_context,
                                          &dk->h_denom_pub,
                                          sizeof (struct GNUNET_HashCode));
 
-        GNUNET_assert (
-          0 ==
-          json_array_append_new (
-            array,
-            denom));
+        /* Finally, add the denomination to the list of denominations in this
+         * group */
+        list = json_object_get (group->json, denoms_key);
+        GNUNET_assert (NULL != list);
+        GNUNET_assert (true == json_is_array (list));
+        GNUNET_assert (0 ==
+                       json_array_append_new (list, entry));
       }
     }
+
+    /* Create the JSON-array of grouped denominations */
+    if (0 <
+        GNUNET_CONTAINER_multihashmap_size (denominations_by_group))
+    {
+      struct GNUNET_CONTAINER_MultiHashMapIterator *iter;
+      struct GNUNET_HashCode all_hashcode;
+      struct GNUNET_HashContext *all_hash_ctx;
+      struct groupData *group = NULL;
+
+      all_hash_ctx =
+        GNUNET_CRYPTO_hash_context_start ();
+
+      iter =
+        GNUNET_CONTAINER_multihashmap_iterator_create (denominations_by_group);
+
+      while (GNUNET_OK ==
+             GNUNET_CONTAINER_multihashmap_iterator_next (iter, NULL, (const
+                                                                       void **)
+                                                          &group))
+      {
+        struct GNUNET_HashCode hc;
+
+        GNUNET_CRYPTO_hash_context_finish (
+          group->hash_context,
+          &hc);
+
+        GNUNET_CRYPTO_hash_context_read (all_hash_ctx,
+                                         &hc,
+                                         sizeof (struct GNUNET_HashCode));
+
+        GNUNET_assert (0 ==
+                       json_object_set (
+                         group->json,
+                         "hash",
+                         GNUNET_JSON_PACK (
+                           GNUNET_JSON_pack_data_auto (NULL, &hc))));
+
+        GNUNET_assert (0 ==
+                       json_array_append_new (
+                         grouped_denominations,
+                         group->json));
+
+        GNUNET_free (group);
+      }
+
+      GNUNET_CONTAINER_multihashmap_iterator_destroy (iter);
+      GNUNET_CONTAINER_multihashmap_destroy (denominations_by_group);
+
+      GNUNET_CRYPTO_hash_context_finish (
+        all_hash_ctx,
+        &all_hashcode);
+
+      /* FIXME-oec: TODO:
+       * sign all_hashcode and add the signature to the /keys response */
+    }
   }
 
   GNUNET_CONTAINER_heap_destroy (heap);
@@ -2165,18 +2339,6 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
   {
     struct GNUNET_HashCode hc;
 
-    /* If age restriction is active and we had at least one denomination of
-     * that sort, we simply add the hash of all age restricted denominations at
-     * the end of the others. */
-    if (0 && have_age_restricted_denoms)
-    {
-      struct GNUNET_HashCode hcr;
-      GNUNET_CRYPTO_hash_context_finish (hash_context_restricted, &hcr);
-      GNUNET_CRYPTO_hash_context_read (hash_context,
-                                       &hcr,
-                                       sizeof (struct GNUNET_HashCode));
-    }
-
     GNUNET_CRYPTO_hash_context_finish (hash_context,
                                        &hc);
 
@@ -2187,14 +2349,12 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
                     sctx.signkeys,
                     recoup,
                     denoms,
-                    age_restricted_denoms))
+                    grouped_denominations))
     {
       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                   "Failed to generate key response data for %s\n",
                   GNUNET_TIME_timestamp2s (last_cpd));
       json_decref (denoms);
-      if (0 && NULL != age_restricted_denoms)
-        json_decref (age_restricted_denoms);
       json_decref (sctx.signkeys);
       json_decref (recoup);
       return GNUNET_SYSERR;
@@ -2210,8 +2370,6 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
   json_decref (sctx.signkeys);
   json_decref (recoup);
   json_decref (denoms);
-  if (NULL != age_restricted_denoms)
-    json_decref (age_restricted_denoms);
   return GNUNET_OK;
 }
 
@@ -2387,11 +2545,13 @@ build_key_state (struct HelperState *hs,
                        true);
     return NULL;
   }
+
   if (management_only)
   {
     ksh->management_only = true;
     return ksh;
   }
+
   if (GNUNET_OK !=
       finish_keys_response (ksh))
   {
@@ -2401,6 +2561,7 @@ build_key_state (struct HelperState *hs,
                        true);
     return NULL;
   }
+
   return ksh;
 }
 

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