diff options
Diffstat (limited to 'src/util/util.c')
-rw-r--r-- | src/util/util.c | 260 |
1 files changed, 239 insertions, 21 deletions
diff --git a/src/util/util.c b/src/util/util.c index 2d10fd69d..da5727487 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2020 Taler Systems SA + Copyright (C) 2014-2023 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -19,16 +19,20 @@ * @author Sree Harsha Totakura <sreeharsha@totakura.in> * @author Florian Dold * @author Benedikt Mueller + * @author Christian Grothoff */ #include "platform.h" #include "taler_util.h" +#include "taler_attributes.h" +#include <gnunet/gnunet_json_lib.h> +#include <unistr.h> const char * TALER_b2s (const void *buf, size_t buf_size) { - static GNUNET_THREAD_LOCAL char ret[9]; + static TALER_THREAD_LOCAL char ret[9]; struct GNUNET_HashCode hc; char *tmp; @@ -37,9 +41,9 @@ TALER_b2s (const void *buf, &hc); tmp = GNUNET_STRINGS_data_to_string_alloc (&hc, sizeof (hc)); - memcpy (ret, - tmp, - 8); + GNUNET_memcpy (ret, + tmp, + 8); GNUNET_free (tmp); ret[8] = '\0'; return ret; @@ -82,8 +86,6 @@ TALER_global_fee_set_hton (struct TALER_GlobalFeeSetNBOP *nbo, { TALER_amount_hton (&nbo->history, &fees->history); - TALER_amount_hton (&nbo->kyc, - &fees->kyc); TALER_amount_hton (&nbo->account, &fees->account); TALER_amount_hton (&nbo->purse, @@ -97,8 +99,6 @@ TALER_global_fee_set_ntoh (struct TALER_GlobalFeeSet *fees, { TALER_amount_ntoh (&fees->history, &nbo->history); - TALER_amount_ntoh (&fees->kyc, - &nbo->kyc); TALER_amount_ntoh (&fees->account, &nbo->account); TALER_amount_ntoh (&fees->purse, @@ -114,8 +114,6 @@ TALER_wire_fee_set_hton (struct TALER_WireFeeSetNBOP *nbo, &fees->wire); TALER_amount_hton (&nbo->closing, &fees->closing); - TALER_amount_hton (&nbo->wad, - &fees->wad); } @@ -127,8 +125,6 @@ TALER_wire_fee_set_ntoh (struct TALER_WireFeeSet *fees, &nbo->wire); TALER_amount_ntoh (&fees->closing, &nbo->closing); - TALER_amount_ntoh (&fees->wad, - &nbo->wad); } @@ -142,10 +138,6 @@ TALER_global_fee_set_cmp (const struct TALER_GlobalFeeSet *f1, &f2->history); if (0 != ret) return ret; - ret = TALER_amount_cmp (&f1->kyc, - &f2->kyc); - if (0 != ret) - return ret; ret = TALER_amount_cmp (&f1->account, &f2->account); if (0 != ret) @@ -172,10 +164,6 @@ TALER_wire_fee_set_cmp (const struct TALER_WireFeeSet *f1, &f2->closing); if (0 != ret) return ret; - ret = TALER_amount_cmp (&f1->wad, - &f2->wad); - if (0 != ret) - return ret; return 0; } @@ -217,6 +205,189 @@ TALER_denom_fee_check_currency ( } +/** + * Dump character in the low range into @a buf + * following RFC 8785. + * + * @param[in,out] buf buffer to modify + * @param val value to dump + */ +static void +lowdump (struct GNUNET_Buffer *buf, + unsigned char val) +{ + char scratch[7]; + + switch (val) + { + case 0x8: + GNUNET_buffer_write (buf, + "\\b", + 2); + break; + case 0x9: + GNUNET_buffer_write (buf, + "\\t", + 2); + break; + case 0xA: + GNUNET_buffer_write (buf, + "\\n", + 2); + break; + case 0xC: + GNUNET_buffer_write (buf, + "\\f", + 2); + break; + case 0xD: + GNUNET_buffer_write (buf, + "\\r", + 2); + break; + default: + GNUNET_snprintf (scratch, + sizeof (scratch), + "\\u%04x", + (unsigned int) val); + GNUNET_buffer_write (buf, + scratch, + 6); + break; + } +} + + +size_t +TALER_rfc8785encode (char **inp) +{ + struct GNUNET_Buffer buf = { 0 }; + size_t left = strlen (*inp) + 1; + size_t olen; + char *in = *inp; + const char *pos = in; + + GNUNET_buffer_prealloc (&buf, + left + 40); + buf.warn_grow = 0; /* disable, + 40 is just a wild guess */ + while (1) + { + int mbl = u8_mblen ((unsigned char *) pos, + left); + unsigned char val; + + if (0 == mbl) + break; + val = (unsigned char) *pos; + if ( (1 == mbl) && + (val <= 0x1F) ) + { + /* Should not happen, as input is produced by + * JSON stringification */ + GNUNET_break (0); + lowdump (&buf, + val); + } + else if ( (1 == mbl) && ('\\' == *pos) ) + { + switch (*(pos + 1)) + { + case '\\': + mbl = 2; + GNUNET_buffer_write (&buf, + pos, + mbl); + break; + case 'u': + { + unsigned int num; + uint32_t n32; + unsigned char res[8]; + size_t rlen; + + GNUNET_assert ( (1 == + sscanf (pos + 2, + "%4x", + &num)) || + (1 == + sscanf (pos + 2, + "%4X", + &num)) ); + mbl = 6; + n32 = (uint32_t) num; + rlen = sizeof (res); + u32_to_u8 (&n32, + 1, + res, + &rlen); + if ( (1 == rlen) && + (res[0] <= 0x1F) ) + { + lowdump (&buf, + res[0]); + } + else + { + GNUNET_buffer_write (&buf, + (const char *) res, + rlen); + } + } + break; + default: + mbl = 2; + GNUNET_buffer_write (&buf, + pos, + mbl); + break; + } + } + else + { + GNUNET_buffer_write (&buf, + pos, + mbl); + } + left -= mbl; + pos += mbl; + } + + /* 0-terminate buffer */ + GNUNET_buffer_write (&buf, + "", + 1); + GNUNET_free (in); + *inp = GNUNET_buffer_reap (&buf, + &olen); + return olen; +} + + +/** + * Hash normalized @a j JSON object or array and + * store the result in @a hc. + * + * @param j JSON to hash + * @param[out] hc where to write the hash + */ +void +TALER_json_hash (const json_t *j, + struct GNUNET_HashCode *hc) +{ + char *cstr; + size_t clen; + + cstr = json_dumps (j, + JSON_COMPACT | JSON_SORT_KEYS); + GNUNET_assert (NULL != cstr); + clen = TALER_rfc8785encode (&cstr); + GNUNET_CRYPTO_hash (cstr, + clen, + hc); + GNUNET_free (cstr); +} + + #ifdef __APPLE__ char * strchrnul (const char *s, @@ -234,4 +405,51 @@ strchrnul (const char *s, #endif +void +TALER_CRYPTO_attributes_to_kyc_prox ( + const json_t *attr, + struct GNUNET_ShortHashCode *kyc_prox) +{ + const char *name = NULL; + const char *birthdate = NULL; + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_string (TALER_ATTRIBUTE_FULL_NAME, + &name), + NULL), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_string (TALER_ATTRIBUTE_BIRTHDATE, + &birthdate), + NULL), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (attr, + spec, + NULL, NULL)) + { + GNUNET_break (0); + memset (kyc_prox, + 0, + sizeof (*kyc_prox)); + return; + } + GNUNET_assert (GNUNET_YES == + GNUNET_CRYPTO_kdf ( + kyc_prox, + sizeof (*kyc_prox), + name, + (NULL == name) + ? 0 + : strlen (name), + birthdate, + (NULL == birthdate) + ? 0 + : strlen (birthdate), + NULL, + 0)); +} + + /* end of util.c */ |