diff options
author | Christian Grothoff <christian@grothoff.org> | 2021-06-16 23:12:21 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2021-06-16 23:12:21 +0200 |
commit | 6680f9b4ef37db66880d774d7dc9f97e7d639f13 (patch) | |
tree | 4e76312792392226bf4a281c8d142d926aeac4b1 /src | |
parent | 9db945471f67b6063f86c6c5b91296d480f0cd80 (diff) | |
download | exchange-6680f9b4ef37db66880d774d7dc9f97e7d639f13.tar.xz |
implement logic to replace 'true' forgettable salts with random salts, fix object deletion when forgetting
Diffstat (limited to 'src')
-rw-r--r-- | src/include/taler_json_lib.h | 13 | ||||
-rw-r--r-- | src/json/json.c | 98 | ||||
-rw-r--r-- | src/json/test_json.c | 15 |
3 files changed, 121 insertions, 5 deletions
diff --git a/src/include/taler_json_lib.h b/src/include/taler_json_lib.h index bf8c22177..aefc28061 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 faae36d62..fe2ea8382 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 b3c36837f..bedea76ac 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", |