summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2021-06-16 23:12:21 +0200
committerChristian Grothoff <christian@grothoff.org>2021-06-16 23:12:21 +0200
commit6680f9b4ef37db66880d774d7dc9f97e7d639f13 (patch)
tree4e76312792392226bf4a281c8d142d926aeac4b1
parent9db945471f67b6063f86c6c5b91296d480f0cd80 (diff)
downloadexchange-6680f9b4ef37db66880d774d7dc9f97e7d639f13.tar.gz
exchange-6680f9b4ef37db66880d774d7dc9f97e7d639f13.tar.bz2
exchange-6680f9b4ef37db66880d774d7dc9f97e7d639f13.zip
implement logic to replace 'true' forgettable salts with random salts, fix object deletion when forgetting
-rw-r--r--src/include/taler_json_lib.h13
-rw-r--r--src/json/json.c98
-rw-r--r--src/json/test_json.c15
3 files changed, 121 insertions, 5 deletions
diff --git a/src/include/taler_json_lib.h b/src/include/taler_json_lib.h
index bf8c2217..aefc2806 100644
--- a/src/include/taler_json_lib.h
+++ b/src/include/taler_json_lib.h
@@ -199,6 +199,19 @@ TALER_JSON_contract_hash (const json_t *json,
/**
+ * Take a given contract with "forgettable" fields marked
+ * but with 'True' instead of a real salt. Replaces all
+ * 'True' values with proper random salts. Fails if any
+ * forgettable markers are neither 'True' nor valid salts.
+ *
+ * @param[in,out] json JSON to transform
+ * @return #GNUNET_OK on success
+ */
+int
+TALER_JSON_contract_seed_forgettable (json_t *json);
+
+
+/**
* Mark part of a contract object as 'forgettable'.
*
* @param[in,out] json some JSON object to modify
diff --git a/src/json/json.c b/src/json/json.c
index faae36d6..fe2ea838 100644
--- a/src/json/json.c
+++ b/src/json/json.c
@@ -506,9 +506,8 @@ TALER_JSON_contract_part_forget (json_t *json,
}
/* finally, set 'forgotten' field to null */
if (0 !=
- json_object_set_new (json,
- field,
- json_null ()))
+ json_object_del (json,
+ field))
{
GNUNET_break (0);
return GNUNET_SYSERR;
@@ -518,6 +517,99 @@ TALER_JSON_contract_part_forget (json_t *json,
/**
+ * Look over all of the values of a '$forgettable' object. Replace 'True'
+ * values with proper random salts. Fails if any forgettable values are
+ * neither 'True' nor valid salts (strings).
+ *
+ * @param[in,out] f JSON to transform
+ * @return #GNUNET_OK on success
+ */
+static int
+seed_forgettable (json_t *f)
+{
+ const char *key;
+ json_t *val;
+
+ json_object_foreach (f,
+ key,
+ val)
+ {
+ if (json_is_string (val))
+ continue;
+ if (json_is_true (val))
+ {
+ struct GNUNET_ShortHashCode sh;
+
+ GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
+ &sh,
+ sizeof (sh));
+ json_object_set_new (f,
+ key,
+ GNUNET_JSON_from_data_auto (&sh));
+ continue;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Forgettable field `%s' has invalid value\n",
+ key);
+ return GNUNET_SYSERR;
+ }
+ return GNUNET_OK;
+}
+
+
+/**
+ * Take a given contract with "forgettable" fields marked
+ * but with 'True' instead of a real salt. Replaces all
+ * 'True' values with proper random salts. Fails if any
+ * forgettable markers are neither 'True' nor valid salts.
+ *
+ * @param[in,out] json JSON to transform
+ * @return #GNUNET_OK on success
+ */
+int
+TALER_JSON_contract_seed_forgettable (json_t *json)
+{
+ if (json_is_object (json))
+ {
+ const char *key;
+ json_t *val;
+
+ json_object_foreach (json,
+ key,
+ val)
+ {
+ if (0 == strcmp ("$forgettable",
+ key))
+ {
+ if (GNUNET_OK !=
+ seed_forgettable (val))
+ return GNUNET_SYSERR;
+ continue;
+ }
+ if (GNUNET_OK !=
+ TALER_JSON_contract_seed_forgettable (val))
+ return GNUNET_SYSERR;
+ }
+ }
+ if (json_is_array (json))
+ {
+ size_t index;
+ json_t *val;
+
+ json_array_foreach (json,
+ index,
+ val)
+ {
+ if (GNUNET_OK !=
+ TALER_JSON_contract_seed_forgettable (val))
+ return GNUNET_SYSERR;
+ }
+ }
+ return GNUNET_OK;
+}
+
+
+/**
* Parse a json path.
*
* @param obj the object that the path is relative to.
diff --git a/src/json/test_json.c b/src/json/test_json.c
index b3c36837..bedea76a 100644
--- a/src/json/test_json.c
+++ b/src/json/test_json.c
@@ -96,6 +96,17 @@ test_contract (void)
json_t *c3;
json_t *c4;
+ c1 = json_pack ("{s:s, s:{s:s, s:{s:b}}}",
+ "k1", "v1",
+ "k2", "n1", "n2",
+ /***/ "$forgettable", "n1", true);
+ GNUNET_assert (GNUNET_OK ==
+ TALER_JSON_contract_seed_forgettable (c1));
+ GNUNET_assert (GNUNET_OK ==
+ TALER_JSON_contract_hash (c1,
+ &h1));
+ json_decref (c1);
+
c1 = json_pack ("{s:s, s:{s:s, s:{s:s}}}",
"k1", "v1",
"k2", "n1", "n2",
@@ -147,6 +158,7 @@ test_contract (void)
GNUNET_assert (GNUNET_OK ==
TALER_JSON_contract_part_forget (c1,
"k2"));
+ json_dumpf (c1, stderr, JSON_INDENT (2));
GNUNET_assert (GNUNET_OK ==
TALER_JSON_contract_hash (c1,
&h2));
@@ -159,7 +171,6 @@ test_contract (void)
return 1;
}
-
c1 = json_pack ("{s:I, s:{s:s}, s:{s:b, s:{s:s}}, s:{s:s}}",
"k1", 1,
"$forgettable", "k1", "SALT",
@@ -178,7 +189,7 @@ test_contract (void)
sizeof (h1));
if (0 !=
strcmp (s,
- "48YVST0SZJXWNG3KAD14SSK3AD0T5V01W5AE6E76DYKMJSC5BQ19M0FZ7CZP5JY26FC4AFXTXRGEVSQ1NSKPQ1DQ4GS9C4SAECG5RZ8"))
+ "VDE8JPX0AEEE3EX1K8E11RYEWSZQKGGZCV6BWTE4ST1C8711P7H850Z7F2Q2HSSYETX87ERC2JNHWB7GTDWTDWMM716VKPSRBXD7SRR"))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Invalid reference hash: %s\n",