gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] branch master updated: [age restriction] progress 11/n


From: gnunet
Subject: [taler-exchange] branch master updated: [age restriction] progress 11/n
Date: Mon, 10 Jan 2022 00:04:56 +0100

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

oec pushed a commit to branch master
in repository exchange.

The following commit(s) were added to refs/heads/master by this push:
     new e30989c9 [age restriction] progress 11/n
e30989c9 is described below

commit e30989c9303105770504f1bdbf26d843adf19468
Author: Özgür Kesim <oec-taler@kesim.org>
AuthorDate: Mon Jan 10 00:04:23 2022 +0100

    [age restriction] progress 11/n
    
    Parse age restriction information from "/keys"
    - parse "age_restriction" extension, extract mask for age groups
    - parse denominations from "age_restricted_denoms", too, if available
---
 src/include/taler_exchange_service.h |  10 ++
 src/include/taler_extensions.h       |   2 +-
 src/lib/exchange_api_handle.c        | 178 +++++++++++++++++++++++++----------
 src/util/extension_age_restriction.c |   2 +-
 4 files changed, 142 insertions(+), 50 deletions(-)

diff --git a/src/include/taler_exchange_service.h 
b/src/include/taler_exchange_service.h
index 04b731b3..6976293c 100644
--- a/src/include/taler_exchange_service.h
+++ b/src/include/taler_exchange_service.h
@@ -159,6 +159,11 @@ struct TALER_EXCHANGE_DenomPublicKey
    * revoked by the exchange.
    */
   bool revoked;
+
+  /**
+   * Is the denomination age-restricted?
+   */
+  bool age_restricted;
 };
 
 
@@ -282,6 +287,11 @@ struct TALER_EXCHANGE_Keys
    */
   struct GNUNET_TIME_Timestamp last_denom_issue_date;
 
+  /**
+   * If age restriction is enabled on the exchange, we get an non-zero age_mask
+   */
+  struct TALER_AgeMask age_mask;
+
   /**
    * Length of the @e sign_keys array (number of valid entries).
    */
diff --git a/src/include/taler_extensions.h b/src/include/taler_extensions.h
index 199776eb..243811eb 100644
--- a/src/include/taler_extensions.h
+++ b/src/include/taler_extensions.h
@@ -110,7 +110,7 @@ TALER_extension_get_by_name (const char *name,
  * @return Error, if age groups were invalid, OK otherwise.
  */
 enum TALER_Extension_ReturnValue
-TALER_parse_age_group_string (char *groups,
+TALER_parse_age_group_string (const char *groups,
                               struct TALER_AgeMask *mask);
 
 /**
diff --git a/src/lib/exchange_api_handle.c b/src/lib/exchange_api_handle.c
index df501f0b..ac0e0584 100644
--- a/src/lib/exchange_api_handle.c
+++ b/src/lib/exchange_api_handle.c
@@ -30,6 +30,7 @@
 #include "taler_exchange_service.h"
 #include "taler_auditor_service.h"
 #include "taler_signatures.h"
+#include "taler_extensions.h"
 #include "exchange_api_handle.h"
 #include "exchange_api_curl_defaults.h"
 #include "backoff.h"
@@ -345,6 +346,7 @@ parse_json_denomkey (struct TALER_EXCHANGE_DenomPublicKey 
*denom_key,
     GNUNET_JSON_spec_end ()
   };
 
+
   if (GNUNET_OK !=
       GNUNET_JSON_parse (denom_key_obj,
                          spec,
@@ -761,6 +763,7 @@ decode_keys_json (const json_t *resp_obj,
       return GNUNET_SYSERR;
     }
   }
+
   /* parse the master public key and issue date of the response */
   if (check_sig)
     hash_context = GNUNET_CRYPTO_hash_context_start ();
@@ -791,63 +794,142 @@ decode_keys_json (const json_t *resp_obj,
     }
   }
 
-  /* parse the denomination keys, merging with the
-     possibly EXISTING array as required (/keys cherry picking) */
+  /* Parse the supported extension(s): age-restriction. */
+  /* TODO: maybe lift this into a FP in TALER_Extension ? */
   {
-    json_t *denom_keys_array;
-    json_t *denom_key_obj;
-    unsigned int index;
+    json_t *age_restriction = json_object_get (resp_obj,
+                                               "age_restriction");
 
-    EXITIF (NULL == (denom_keys_array =
-                       json_object_get (resp_obj,
-                                        "denoms")));
-    EXITIF (JSON_ARRAY != json_typeof (denom_keys_array));
+    if (NULL != age_restriction)
+    {
+      bool critical;
+      const char *version;
+      const char *age_groups;
+      struct GNUNET_JSON_Specification spec[] = {
+        GNUNET_JSON_spec_bool ("critical",
+                               &critical),
+        GNUNET_JSON_spec_string ("version",
+                                 &version),
+        GNUNET_JSON_spec_string ("age_groups",
+                                 &age_groups),
+        GNUNET_JSON_spec_end ()
+      };
 
-    json_array_foreach (denom_keys_array, index, denom_key_obj) {
-      struct TALER_EXCHANGE_DenomPublicKey dk;
-      bool found = false;
+      if (GNUNET_OK !=
+          GNUNET_JSON_parse (age_restriction,
+                             spec,
+                             NULL, NULL))
+      {
+        GNUNET_break_op (0);
+        return GNUNET_SYSERR;
+      }
 
-      memset (&dk,
-              0,
-              sizeof (dk));
-      EXITIF (GNUNET_SYSERR ==
-              parse_json_denomkey (&dk,
-                                   check_sig,
-                                   denom_key_obj,
-                                   &key_data->master_pub,
-                                   hash_context));
-
-      for (unsigned int j = 0;
-           j<key_data->num_denom_keys;
-           j++)
+      if (critical || // do we care?
+          0 != strncmp (version, "1", 1) ) /* TODO: better compatibility check 
*/
       {
-        if (0 == denoms_cmp (&dk,
-                             &key_data->denom_keys[j]))
-        {
-          found = true;
-          break;
-        }
+        GNUNET_break_op (0);
+        return GNUNET_SYSERR;
       }
-      if (found)
+
+      if (TALER_Extension_OK !=
+          TALER_parse_age_group_string (age_groups,
+                                        &key_data->age_mask))
       {
-        /* 0:0:0 did not support /keys cherry picking */
-        TALER_LOG_DEBUG ("Skipping denomination key: already know it\n");
-        TALER_denom_pub_free (&dk.key);
-        continue;
+        // TODO: print more specific error?
+        GNUNET_break_op (0);
+        return GNUNET_SYSERR;
       }
-      if (key_data->denom_keys_size == key_data->num_denom_keys)
-        GNUNET_array_grow (key_data->denom_keys,
-                           key_data->denom_keys_size,
-                           key_data->denom_keys_size * 2 + 2);
-      key_data->denom_keys[key_data->num_denom_keys++] = dk;
-
-      /* Update "last_denom_issue_date" */
-      TALER_LOG_DEBUG ("Adding denomination key that is valid_until %s\n",
-                       GNUNET_TIME_timestamp2s (dk.valid_from));
-      key_data->last_denom_issue_date
-        = GNUNET_TIME_timestamp_max (key_data->last_denom_issue_date,
-                                     dk.valid_from);
+    }
+  }
+
+  /* parse the denomination keys, merging with the
+     possibly EXISTING array as required (/keys cherry picking) */
+  {
+    /* The denominations can be in "denoms" and (optionally) in
+     * "age_restricted_denoms"
+     */
+    struct
+    { char *name;
+      bool is_optional_age_restriction;} hive[2] = {
+      { "denoms",                false },
+      { "age_restricted_denoms", true  },
     };
+
+    for (size_t s = 0; s < sizeof(hive) / sizeof(hive[0]); s++)
+    {
+      json_t *denom_keys_array;
+      json_t *denom_key_obj;
+      unsigned int index;
+
+      denom_keys_array = json_object_get (resp_obj,
+                                          hive[s].name);
+
+      EXITIF (NULL == denom_keys_array &&
+              ! hive[s].is_optional_age_restriction);
+
+      if (NULL == denom_keys_array &&
+          hive[s].is_optional_age_restriction)
+        continue;
+
+      /* if "age_restricted_denoms" exists, age-restriction better be enabled
+       * (that is: mask non-zero) */
+      EXITIF (NULL != denom_keys_array &&
+              hive[s].is_optional_age_restriction &&
+              0 == key_data->age_mask.mask);
+
+      EXITIF (JSON_ARRAY != json_typeof (denom_keys_array));
+
+      json_array_foreach (denom_keys_array, index, denom_key_obj) {
+        struct TALER_EXCHANGE_DenomPublicKey dk;
+        bool found = false;
+
+        memset (&dk,
+                0,
+                sizeof (dk));
+        EXITIF (GNUNET_SYSERR ==
+                parse_json_denomkey (&dk,
+                                     check_sig,
+                                     denom_key_obj,
+                                     &key_data->master_pub,
+                                     hash_context));
+
+        /* Mark age restriction according where we got this denomination from,
+         * "denoms" or "age_restricted_denoms" */
+        if (hive[s].is_optional_age_restriction)
+          dk.age_restricted = true;
+
+        for (unsigned int j = 0;
+             j<key_data->num_denom_keys;
+             j++)
+        {
+          if (0 == denoms_cmp (&dk,
+                               &key_data->denom_keys[j]))
+          {
+            found = true;
+            break;
+          }
+        }
+        if (found)
+        {
+          /* 0:0:0 did not support /keys cherry picking */
+          TALER_LOG_DEBUG ("Skipping denomination key: already know it\n");
+          TALER_denom_pub_free (&dk.key);
+          continue;
+        }
+        if (key_data->denom_keys_size == key_data->num_denom_keys)
+          GNUNET_array_grow (key_data->denom_keys,
+                             key_data->denom_keys_size,
+                             key_data->denom_keys_size * 2 + 2);
+        key_data->denom_keys[key_data->num_denom_keys++] = dk;
+
+        /* Update "last_denom_issue_date" */
+        TALER_LOG_DEBUG ("Adding denomination key that is valid_until %s\n",
+                         GNUNET_TIME_timestamp2s (dk.valid_from));
+        key_data->last_denom_issue_date
+          = GNUNET_TIME_timestamp_max (key_data->last_denom_issue_date,
+                                       dk.valid_from);
+      };
+    }
   }
 
   /* parse the auditor information */
diff --git a/src/util/extension_age_restriction.c 
b/src/util/extension_age_restriction.c
index 42a58b2e..b29a8ca8 100644
--- a/src/util/extension_age_restriction.c
+++ b/src/util/extension_age_restriction.c
@@ -80,7 +80,7 @@ TALER_get_age_mask (const struct GNUNET_CONFIGURATION_Handle 
*cfg,
  * @return Error if string was invalid, OK otherwise.
  */
 enum TALER_Extension_ReturnValue
-TALER_parse_age_group_string (char *groups,
+TALER_parse_age_group_string (const char *groups,
                               struct TALER_AgeMask *mask)
 {
   enum TALER_Extension_ReturnValue ret = TALER_Extension_ERROR_SYS;

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