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:
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;