donau

Donation authority for GNU Taler (experimental)
Log | Files | Refs | Submodules | README | LICENSE

commit a21270e3b3bc38c0b46be31086324eaffde827a6
parent 860e5d15a4ef575591336153ca37efbebef642f4
Author: Christian Grothoff <christian@grothoff.org>
Date:   Tue, 23 Sep 2025 11:00:50 +0200

enforce donau configuration values are sane (#10445)

Diffstat:
Msrc/donau/donau-httpd_keys.c | 5++---
Msrc/lib/donau_api_handle.c | 21+++++++++++++--------
Msrc/util/donau-secmod-cs.c | 153+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Msrc/util/donau-secmod-rsa.c | 153+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
4 files changed, 317 insertions(+), 15 deletions(-)

diff --git a/src/donau/donau-httpd_keys.c b/src/donau/donau-httpd_keys.c @@ -727,7 +727,6 @@ helper_rsa_cb ( du, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); - qs = DH_plugin->insert_donation_unit ( DH_plugin->cls, &du->h_donation_unit_pub, @@ -1313,7 +1312,7 @@ DH_keys_donation_unit_batch_sign ( { case GNUNET_CRYPTO_BSA_RSA: /* See DONAU_donation_unit_pub_hash: we guarantee that these - hashes are equivalent! */ + hashes are equivalent! */ rsrs[rsrs_pos].h_rsa = (const struct TALER_RsaPubHashP *) &du->h_donation_unit_pub; rsrs[rsrs_pos].msg @@ -1324,7 +1323,7 @@ DH_keys_donation_unit_batch_sign ( break; case GNUNET_CRYPTO_BSA_CS: /* See DONAU_donation_unit_pub_hash: we guarantee that these - hashes are equivalent! */ + hashes are equivalent! */ csrs[csrs_pos].h_cs = (const struct TALER_CsPubHashP *) &du->h_donation_unit_pub; csrs[csrs_pos].blinded_planchet diff --git a/src/lib/donau_api_handle.c b/src/lib/donau_api_handle.c @@ -673,7 +673,9 @@ DONAU_select_donation_unit_keys_for_amount ( while (i < n_duv) { - int cmp = TALER_amount_cmp (&duv[i].value, &remaining); + int cmp = TALER_amount_cmp (&duv[i].value, + &remaining); + if (cmp <= 0) { /* Take as many as we can of duv[i] without overshooting */ @@ -682,7 +684,8 @@ DONAU_select_donation_unit_keys_for_amount ( struct TALER_Amount tmp; int rc; - if (TALER_amount_cmp (&duv[i].value, &remaining) > 0) + if (TALER_amount_cmp (&duv[i].value, + &remaining) > 0) break; GNUNET_array_append (result, @@ -740,17 +743,19 @@ DONAU_get_donation_amount_from_bkps ( struct TALER_Amount *sum_out) { /* Sanity-checks */ - if ( (NULL == keys) || - (NULL == bkps) || - (0 == num_bkps) || - (NULL == sum_out) ) + if (NULL == bkps) + { + GNUNET_break (0); + return GNUNET_NO; + } + if (0 == num_bkps) { GNUNET_break (0); return GNUNET_NO; } - TALER_amount_set_zero (keys->currency, sum_out); - + TALER_amount_set_zero (keys->currency, + sum_out); if (GNUNET_YES == DONAU_check_bkps_duplication (bkps, num_bkps)) diff --git a/src/util/donau-secmod-cs.c b/src/util/donau-secmod-cs.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2024 Taler Systems SA + Copyright (C) 2014-2025 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 @@ -45,6 +45,155 @@ #define EXIT_INVALIDARGUMENT 2 #endif +#ifndef EXIT_NOTCONFIGURED +/** + * Key configuration settings are missing or invalid. + * Restarting useless. + */ +#define EXIT_NOTCONFIGURED 6 +#endif + + +/** + * Set to true if the configuration is invalid. + */ +static bool config_invalid; + +/** + * Configuration we use. + */ +static const struct GNUNET_CONFIGURATION_Handle *my_cfg; + +/** + * Checks the donau configuration section settings. + * denomination_alias. + * + * @param cls must point to a `struct TALER_SECMOD_Options *` + * @param denomination_alias name of the denomination's section in the configuration + */ +static void +load_denominations (void *cls, + const char *denomination_alias) +{ + struct TALER_SECMOD_Options *opts = cls; + struct GNUNET_TIME_Relative r; + + if (0 != strncasecmp (denomination_alias, + opts->cprefix, + strlen (opts->cprefix))) + return; /* not a denomination type definition */ + + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_time (my_cfg, + denomination_alias, + "DURATION_WITHDRAW", + &r)) + { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + denomination_alias, + "DURATION_WITHDRAW"); + opts->global_ret = EXIT_NOTCONFIGURED; + return; + } + if (GNUNET_TIME_relative_cmp (r, + !=, + GNUNET_TIME_UNIT_YEARS)) + { + GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, + denomination_alias, + "DURATION_WITHDRAW", + "Must be exactly 1 year for Donau"); + opts->global_ret = EXIT_NOTCONFIGURED; + return; + } + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_time (my_cfg, + denomination_alias, + "ANCHOR_ROUND", + &r)) + { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + denomination_alias, + "ANCHOR_ROUND"); + opts->global_ret = EXIT_NOTCONFIGURED; + return; + } + if (GNUNET_TIME_relative_cmp (r, + !=, + GNUNET_TIME_UNIT_YEARS)) + { + GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, + denomination_alias, + "ANCHOR_ROUND", + "Must be exactly 1 year for Donau"); + opts->global_ret = EXIT_NOTCONFIGURED; + return; + } +} + + +/** + * Wrapper around #TALER_SECMOD_rsa_run() that checks that the + * configuration abides by the Donau-constraints. + * + * @param cls must point to a `struct TALER_SECMOD_Options *` + * @param args remaining command-line arguments + * @param cfgfile name of the configuration file used (for saving, can be NULL!) + * @param cfg configuration + */ +static void +donau_cs_run (void *cls, + char *const *args, + const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + struct TALER_SECMOD_Options *opts = cls; + char *secname; + struct GNUNET_TIME_Relative overlap_duration; + + my_cfg = cfg; + GNUNET_asprintf (&secname, + "%s-secmod-rsa", + opts->section); + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_time (cfg, + secname, + "OVERLAP_DURATION", + &overlap_duration)) + { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + secname, + "OVERLAP_DURATION"); + opts->global_ret = EXIT_NOTCONFIGURED; + GNUNET_free (secname); + return; + } + if (! GNUNET_TIME_relative_is_zero (overlap_duration)) + { + GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, + secname, + "OVERLAP_DURATION", + "must be zero for Donau"); + opts->global_ret = EXIT_NOTCONFIGURED; + GNUNET_free (secname); + return; + } + GNUNET_free (secname); + GNUNET_CONFIGURATION_iterate_sections (cfg, + &load_denominations, + opts); + if (config_invalid) + { + opts->global_ret = EXIT_NOTCONFIGURED; + return; + } + TALER_SECMOD_cs_run (cls, + args, + cfgfile, + cfg); +} + + /** * The entry point. * @@ -76,7 +225,7 @@ main (int argc, "donau-secmod-cs", "Handle private CS key operations for a Donau", options, - &TALER_SECMOD_cs_run, + &donau_cs_run, &opts); if (GNUNET_NO == ret) return EXIT_SUCCESS; diff --git a/src/util/donau-secmod-rsa.c b/src/util/donau-secmod-rsa.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2024 Taler Systems SA + Copyright (C) 2014-2025 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 @@ -45,6 +45,155 @@ #define EXIT_INVALIDARGUMENT 2 #endif +#ifndef EXIT_NOTCONFIGURED +/** + * Key configuration settings are missing or invalid. + * Restarting useless. + */ +#define EXIT_NOTCONFIGURED 6 +#endif + + +/** + * Set to true if the configuration is invalid. + */ +static bool config_invalid; + +/** + * Configuration we use. + */ +static const struct GNUNET_CONFIGURATION_Handle *my_cfg; + +/** + * Checks the donau configuration section settings. + * denomination_alias. + * + * @param cls must point to a `struct TALER_SECMOD_Options *` + * @param denomination_alias name of the denomination's section in the configuration + */ +static void +load_denominations (void *cls, + const char *denomination_alias) +{ + struct TALER_SECMOD_Options *opts = cls; + struct GNUNET_TIME_Relative r; + + if (0 != strncasecmp (denomination_alias, + opts->cprefix, + strlen (opts->cprefix))) + return; /* not a denomination type definition */ + + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_time (my_cfg, + denomination_alias, + "DURATION_WITHDRAW", + &r)) + { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + denomination_alias, + "DURATION_WITHDRAW"); + opts->global_ret = EXIT_NOTCONFIGURED; + return; + } + if (GNUNET_TIME_relative_cmp (r, + !=, + GNUNET_TIME_UNIT_YEARS)) + { + GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, + denomination_alias, + "DURATION_WITHDRAW", + "Must be exactly 1 year for Donau"); + opts->global_ret = EXIT_NOTCONFIGURED; + return; + } + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_time (my_cfg, + denomination_alias, + "ANCHOR_ROUND", + &r)) + { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + denomination_alias, + "ANCHOR_ROUND"); + opts->global_ret = EXIT_NOTCONFIGURED; + return; + } + if (GNUNET_TIME_relative_cmp (r, + !=, + GNUNET_TIME_UNIT_YEARS)) + { + GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, + denomination_alias, + "ANCHOR_ROUND", + "Must be exactly 1 year for Donau"); + opts->global_ret = EXIT_NOTCONFIGURED; + return; + } +} + + +/** + * Wrapper around #TALER_SECMOD_rsa_run() that checks that the + * configuration abides by the Donau-constraints. + * + * @param cls must point to a `struct TALER_SECMOD_Options *` + * @param args remaining command-line arguments + * @param cfgfile name of the configuration file used (for saving, can be NULL!) + * @param cfg configuration + */ +static void +donau_rsa_run (void *cls, + char *const *args, + const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + struct TALER_SECMOD_Options *opts = cls; + char *secname; + struct GNUNET_TIME_Relative overlap_duration; + + my_cfg = cfg; + GNUNET_asprintf (&secname, + "%s-secmod-rsa", + opts->section); + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_time (cfg, + secname, + "OVERLAP_DURATION", + &overlap_duration)) + { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + secname, + "OVERLAP_DURATION"); + opts->global_ret = EXIT_NOTCONFIGURED; + GNUNET_free (secname); + return; + } + if (! GNUNET_TIME_relative_is_zero (overlap_duration)) + { + GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, + secname, + "OVERLAP_DURATION", + "must be zero for Donau"); + opts->global_ret = EXIT_NOTCONFIGURED; + GNUNET_free (secname); + return; + } + GNUNET_free (secname); + GNUNET_CONFIGURATION_iterate_sections (cfg, + &load_denominations, + opts); + if (config_invalid) + { + opts->global_ret = EXIT_NOTCONFIGURED; + return; + } + TALER_SECMOD_rsa_run (cls, + args, + cfgfile, + cfg); +} + + /** * The entry point. * @@ -77,7 +226,7 @@ main (int argc, "taler-exchange-secmod-rsa", "Handle private RSA key operations for a Donau", options, - &TALER_SECMOD_rsa_run, + &donau_rsa_run, &opts); if (GNUNET_NO == ret) return EXIT_SUCCESS;