From e6e0cabf084ca4a333718b953bc0b48ac12e7356 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Thu, 27 Jan 2022 20:25:40 +0100 Subject: test and hopefully fix JSON canonicalization --- src/json/json.c | 27 ++++++++++++++++++++++++ src/json/test_json.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 83 insertions(+), 3 deletions(-) (limited to 'src/json') diff --git a/src/json/json.c b/src/json/json.c index bf3b2a0e7..da4472522 100644 --- a/src/json/json.c +++ b/src/json/json.c @@ -144,6 +144,9 @@ rfc8785encode (char **inp) if ( (1 == mbl) && (val <= 0x1F) ) { + /* Should not happen, as input is produced by + * JSON stringification */ + GNUNET_break (0); lowdump (&buf, val); } @@ -193,6 +196,12 @@ rfc8785encode (char **inp) } } break; + default: + mbl = 2; + GNUNET_buffer_write (&buf, + pos, + mbl); + break; } } else @@ -1009,6 +1018,24 @@ TALER_deposit_extension_hash (const json_t *extensions, } +char * +TALER_JSON_canonicalize (const json_t *input) +{ + char *wire_enc; + + if (NULL == (wire_enc = json_dumps (input, + JSON_ENCODE_ANY + | JSON_COMPACT + | JSON_SORT_KEYS))) + { + GNUNET_break (0); + return NULL; + } + rfc8785encode (&wire_enc); + return wire_enc; +} + + enum GNUNET_GenericReturnValue TALER_JSON_extensions_config_hash (const json_t *config, struct TALER_ExtensionConfigHash *ech) diff --git a/src/json/test_json.c b/src/json/test_json.c index a8c1c6d8e..5fe51d467 100644 --- a/src/json/test_json.c +++ b/src/json/test_json.c @@ -160,7 +160,7 @@ test_contract (void) GNUNET_assert (GNUNET_OK == TALER_JSON_contract_part_forget (c1, "k2")); - json_dumpf (c1, stderr, JSON_INDENT (2)); + // json_dumpf (c1, stderr, JSON_INDENT (2)); GNUNET_assert (GNUNET_OK == TALER_JSON_contract_hash (c1, &h2)); @@ -182,7 +182,7 @@ test_contract (void) GNUNET_assert (GNUNET_OK == TALER_JSON_contract_hash (c1, &h1)); - json_dumpf (c1, stderr, JSON_INDENT (2)); + // json_dumpf (c1, stderr, JSON_INDENT (2)); json_decref (c1); { char *s; @@ -330,6 +330,57 @@ test_contract (void) } +static int +test_json_canon (void) +{ + { + json_t *c1; + char *canon; + c1 = json_pack ("{s:s}", + "k1", "Hello\nWorld"); + + canon = TALER_JSON_canonicalize (c1); + GNUNET_assert (NULL != canon); + + printf ("canon: '%s'\n", canon); + + GNUNET_assert (0 == strcmp (canon, + "{\"k1\":\"Hello\\nWorld\"}")); + } + { + json_t *c1; + char *canon; + c1 = json_pack ("{s:s}", + "k1", "Testing “unicode” characters"); + + canon = TALER_JSON_canonicalize (c1); + GNUNET_assert (NULL != canon); + + printf ("canon: '%s'\n", canon); + + GNUNET_assert (0 == strcmp (canon, + "{\"k1\":\"Testing “unicode” characters\"}")); + } + { + json_t *c1; + char *canon; + c1 = json_pack ("{s:s}", + "k1", "low range \x05 chars"); + + canon = TALER_JSON_canonicalize (c1); + GNUNET_assert (NULL != canon); + + printf ("canon: '%s'\n", canon); + + GNUNET_assert (0 == strcmp (canon, + "{\"k1\":\"low range \\u0005 chars\"}")); + } + + + return 0; +} + + static int test_rfc8785 (void) { @@ -348,7 +399,7 @@ test_rfc8785 (void) sizeof (h1)); if (0 != strcmp (s, - "J678K3PW9Y3DG63Z3T7ZYR2P7CEXMVZ2SFPQMABACK9TJRYREPP82542PCJ0P7Y7FAQAMWECDX50XH1RBTWHX6SSJHH6FXRV0JCS6R8")) + "531S33T8ZRGW6548G7T67PMDNGS4Z1D8A2GMB87G3PNKYTW6KGF7Q99XVCGXBKVA2HX6PR5ENJ1PQ5ZTYMMXQB6RM7S82VP7ZG2X5G8")) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid reference hash: %s\n", @@ -377,6 +428,8 @@ main (int argc, return 1; if (0 != test_contract ()) return 2; + if (0 != test_json_canon ()) + return 2; if (0 != test_rfc8785 ()) return 2; return 0; -- cgit v1.2.3