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/json | |
| parent | 9db945471f67b6063f86c6c5b91296d480f0cd80 (diff) | |
implement logic to replace 'true' forgettable salts with random salts, fix object deletion when forgetting
Diffstat (limited to 'src/json')
| -rw-r--r-- | src/json/json.c | 98 | ||||
| -rw-r--r-- | src/json/test_json.c | 15 | 
2 files changed, 108 insertions, 5 deletions
| 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", | 
