From 82a04210fd23a7962566b47caccc8e717a380118 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 12 Oct 2023 16:23:05 +0200 Subject: update private key files and harden checks for currency codes --- src/auditor/auditor.conf | 4 +- src/include/taler_amount_lib.h | 10 +++++ src/testing/Makefile.am | 3 +- src/testing/test_exchange_api.conf | 4 +- .../share/taler/auditor/offline-keys/auditor.priv | Bin 0 -> 32 bytes .../share/taler/exchange-offline/master.priv | Bin 0 -> 32 bytes src/util/amount.c | 41 +++++++++++++++++---- src/util/config.c | 9 +++-- src/util/test_amount.c | 14 +++---- 9 files changed, 62 insertions(+), 23 deletions(-) create mode 100644 src/testing/test_exchange_api_home/.local/share/taler/auditor/offline-keys/auditor.priv create mode 100644 src/testing/test_exchange_api_home/.local/share/taler/exchange-offline/master.priv diff --git a/src/auditor/auditor.conf b/src/auditor/auditor.conf index 5ec703465..3c04d196f 100644 --- a/src/auditor/auditor.conf +++ b/src/auditor/auditor.conf @@ -9,7 +9,7 @@ DB = postgres #TINY_AMOUNT = KUDOS:0.01 # Where do we store the auditor's private key? -AUDITOR_PRIV_FILE = ${TALER_DATA_HOME}/auditor/offline-keys/auditor.priv +AUDITOR_PRIV_FILE = ${TALER_DATA_HOME}auditor/offline-keys/auditor.priv # What is the public key of this auditor? Used for processes that # verify auditor's signatures but have no access to the private key. @@ -26,7 +26,7 @@ SERVE = tcp # Unix domain socket to listen on, # only effective with "SERVE = unix" -UNIXPATH = ${TALER_RUNTIME_DIR}/exchange.http +UNIXPATH = ${TALER_RUNTIME_DIR}exchange.http UNIXPATH_MODE = 660 # HTTP port the auditor listens to diff --git a/src/include/taler_amount_lib.h b/src/include/taler_amount_lib.h index c9a35a2aa..937238d15 100644 --- a/src/include/taler_amount_lib.h +++ b/src/include/taler_amount_lib.h @@ -127,6 +127,16 @@ struct TALER_Amount }; +/** + * Check that the currency code in @a str is well-formed. + * + * @param str currency code name to validate + * @return #GNUNET_OK if @a str is a valid currency code + */ +enum GNUNET_GenericReturnValue +TALER_check_currency (const char *str); + + /** * Parse monetary amount, in the format "T:V.F". * diff --git a/src/testing/Makefile.am b/src/testing/Makefile.am index 116df2c24..c63c76475 100644 --- a/src/testing/Makefile.am +++ b/src/testing/Makefile.am @@ -145,14 +145,13 @@ libtalertesting_la_LIBADD = \ AM_TESTS_ENVIRONMENT=export TALER_PREFIX=$${TALER_PREFIX:-@libdir@};export PATH=$${TALER_PREFIX:-@prefix@}/bin:$$PATH; -# test_bank_api_with_nexus - .NOTPARALLEL: check_PROGRAMS = \ test_auditor_api_cs \ test_auditor_api_rsa \ test_auditor_api_version \ test_bank_api_with_fakebank \ + test_bank_api_with_nexus \ test_exchange_api_cs \ test_exchange_api_rsa \ test_exchange_api_age_restriction_cs \ diff --git a/src/testing/test_exchange_api.conf b/src/testing/test_exchange_api.conf index 66ceb7f4c..1fc87230e 100644 --- a/src/testing/test_exchange_api.conf +++ b/src/testing/test_exchange_api.conf @@ -25,7 +25,7 @@ CURRENCY_ROUND_UNIT = EUR:0.01 [auditor] BASE_URL = "http://localhost:8083/" PORT = 8083 -PUBLIC_KEY = T0XJ9QZ59YDN7QG3RE40SB2HY7W0ASR1EKF4WZDGZ1G159RSQC80 +PUBLIC_KEY = 9QZ7CCC5QFMWE9FVF50MGYWV7JR92SFHY5KHT8A1A2VNHM37VCRG TINY_AMOUNT = EUR:0.01 [auditordb-postgres] @@ -39,7 +39,7 @@ TERMS_ETAG = tos PRIVACY_ETAG = 0 AML_THRESHOLD = EUR:1000000 PORT = 8081 -MASTER_PUBLIC_KEY = 98NJW3CQHZQGQXTY3K85K531XKPAPAVV4Q5V8PYYRR00NJGZWNVG +MASTER_PUBLIC_KEY = QD6H521CBJBW0Z7PRN0JTAGH5JCQ97RDZRPPV5TQZSE78NQRT3KG DB = postgres BASE_URL = "http://localhost:8081/" EXPIRE_SHARD_SIZE ="300 ms" diff --git a/src/testing/test_exchange_api_home/.local/share/taler/auditor/offline-keys/auditor.priv b/src/testing/test_exchange_api_home/.local/share/taler/auditor/offline-keys/auditor.priv new file mode 100644 index 000000000..5b1c8fa05 Binary files /dev/null and b/src/testing/test_exchange_api_home/.local/share/taler/auditor/offline-keys/auditor.priv differ diff --git a/src/testing/test_exchange_api_home/.local/share/taler/exchange-offline/master.priv b/src/testing/test_exchange_api_home/.local/share/taler/exchange-offline/master.priv new file mode 100644 index 000000000..391b6ea73 Binary files /dev/null and b/src/testing/test_exchange_api_home/.local/share/taler/exchange-offline/master.priv differ diff --git a/src/util/amount.c b/src/util/amount.c index 97a1cf46a..88f4b6aae 100644 --- a/src/util/amount.c +++ b/src/util/amount.c @@ -39,6 +39,31 @@ invalidate (struct TALER_Amount *a) } +enum GNUNET_GenericReturnValue +TALER_check_currency (const char *str) +{ + if (strlen (str) >= TALER_CURRENCY_LEN) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Currency code name `%s' is too long\n", + str); + return GNUNET_SYSERR; + } + /* validate str has only legal characters in it! */ + for (unsigned int i = 0; '\0' != str[i]; i++) + { + if ( ('A' > str[i]) || ('Z' < str[i]) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Currency code name `%s' contains illegal characters (only A-Z allowed)\n", + str); + return GNUNET_SYSERR; + } + } + return GNUNET_OK; +} + + enum GNUNET_GenericReturnValue TALER_string_to_amount (const char *str, struct TALER_Amount *amount) @@ -73,12 +98,14 @@ TALER_string_to_amount (const char *str, GNUNET_assert (TALER_CURRENCY_LEN > (colon - str)); for (unsigned int i = 0; icurrency[i] = toupper (str[i]); + amount->currency[i] = str[i]; /* 0-terminate *and* normalize buffer by setting everything to '\0' */ memset (&amount->currency [colon - str], 0, TALER_CURRENCY_LEN - (colon - str)); - + if (GNUNET_OK != + TALER_check_currency (amount->currency)) + return GNUNET_SYSERR; /* skip colon */ value = colon + 1; if ('\0' == value[0]) @@ -193,7 +220,7 @@ TALER_amount_hton (struct TALER_AmountNBO *res, res->value = GNUNET_htonll (d->value); res->fraction = htonl (d->fraction); for (unsigned int i = 0; icurrency[i] = toupper (d->currency[i]); + res->currency[i] = d->currency[i]; } @@ -217,15 +244,15 @@ TALER_amount_set_zero (const char *cur, { size_t slen; - slen = strlen (cur); - if (slen >= TALER_CURRENCY_LEN) + if (GNUNET_OK != + TALER_check_currency (cur)) return GNUNET_SYSERR; + slen = strlen (cur); memset (amount, 0, sizeof (struct TALER_Amount)); for (unsigned int i = 0; icurrency[i] = toupper (cur[i]); - /* FIXME: check currency consists only of legal characters! */ + amount->currency[i] = cur[i]; return GNUNET_OK; } diff --git a/src/util/config.c b/src/util/config.c index 718c3a102..f00d11baa 100644 --- a/src/util/config.c +++ b/src/util/config.c @@ -250,17 +250,20 @@ parse_currencies_cb (void *cls, cpc->failure = true; return; } - if (strlen (str) >= TALER_CURRENCY_LEN) + if (GNUNET_OK != + TALER_check_currency (str)) { GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, section, "CODE", - "Currency code name given is too long"); + "Currency code name given is invalid"); cpc->failure = true; GNUNET_free (str); return; } - /* FIXME: validate str has only legal characters in it! */ + memset (cspec->currency, + 0, + sizeof (cspec->currency)); strcpy (cspec->currency, str); GNUNET_free (str); diff --git a/src/util/test_amount.c b/src/util/test_amount.c index a45b71de7..57d73b14f 100644 --- a/src/util/test_amount.c +++ b/src/util/test_amount.c @@ -78,31 +78,31 @@ main (int argc, /* test conversion with leading zero in fraction */ GNUNET_assert (GNUNET_OK == - TALER_string_to_amount ("eur:0.02", + TALER_string_to_amount ("EUR:0.02", &a2)); - GNUNET_assert (0 == strcasecmp ("eur", + GNUNET_assert (0 == strcasecmp ("EUR", a2.currency)); GNUNET_assert (0 == a2.value); GNUNET_assert (TALER_AMOUNT_FRAC_BASE / 100 * 2 == a2.fraction); c = TALER_amount_to_string (&a2); - GNUNET_assert (0 == strcasecmp ("eur:0.02", + GNUNET_assert (0 == strcasecmp ("EUR:0.02", c)); GNUNET_free (c); /* test conversion with leading space and with fraction */ GNUNET_assert (GNUNET_OK == - TALER_string_to_amount (" eur:4.12", + TALER_string_to_amount (" EUR:4.12", &a2)); - GNUNET_assert (0 == strcasecmp ("eur", + GNUNET_assert (0 == strcasecmp ("EUR", a2.currency)); GNUNET_assert (4 == a2.value); GNUNET_assert (TALER_AMOUNT_FRAC_BASE / 100 * 12 == a2.fraction); /* test use of local currency */ GNUNET_assert (GNUNET_OK == - TALER_string_to_amount (" *LOCAL:4444.1000", + TALER_string_to_amount (" LOCAL:4444.1000", &a3)); - GNUNET_assert (0 == strcasecmp ("*LOCAL", + GNUNET_assert (0 == strcasecmp ("LOCAL", a3.currency)); GNUNET_assert (4444 == a3.value); GNUNET_assert (TALER_AMOUNT_FRAC_BASE / 10 == a3.fraction); -- cgit v1.2.3