exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

commit c8120134fd650a66deb55ab64c1e77d7e06be529
parent b7e6a5b5731221204488abeed84663c715b166e2
Author: Christian Grothoff <christian@grothoff.org>
Date:   Mon,  2 Feb 2026 08:52:55 +0100

ensure secmod RSA anchors all end at the same time

Diffstat:
Msrc/util/secmod_rsa.c | 510+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
Msrc/util/test_helper_cs.conf | 2+-
Msrc/util/test_helper_rsa.c | 5+++--
Msrc/util/test_helper_rsa.conf | 2+-
4 files changed, 322 insertions(+), 197 deletions(-)

diff --git a/src/util/secmod_rsa.c b/src/util/secmod_rsa.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2024 Taler Systems SA + Copyright (C) 2014-2026 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 @@ -97,7 +97,12 @@ struct DenominationKey /** * Time at which this key is supposed to become valid. */ - struct GNUNET_TIME_Timestamp anchor; + struct GNUNET_TIME_Timestamp anchor_start; + + /** + * Time at which this key is supposed to expire (exclusive). + */ + struct GNUNET_TIME_Timestamp anchor_end; /** * Generation when this key was created or revoked. @@ -123,12 +128,12 @@ struct Denomination { /** - * Kept in a DLL. Sorted by #denomination_action_time(). + * Kept in a DLL. */ struct Denomination *next; /** - * Kept in a DLL. Sorted by #denomination_action_time(). + * Kept in a DLL. */ struct Denomination *prev; @@ -354,6 +359,7 @@ generate_response (struct DenominationKey *dk) void *buf; void *p; size_t tlen; + struct GNUNET_TIME_Relative effective_duration; buf_len = GNUNET_CRYPTO_rsa_public_key_encode (dk->denom_pub, &buf); @@ -366,12 +372,19 @@ generate_response (struct DenominationKey *dk) an->header.type = htons (TALER_HELPER_RSA_MT_AVAIL); an->pub_size = htons ((uint16_t) buf_len); an->section_name_len = htons ((uint16_t) nlen); - an->anchor_time = GNUNET_TIME_timestamp_hton (dk->anchor); - an->duration_withdraw = GNUNET_TIME_relative_hton (denom->duration_withdraw); + an->anchor_time = GNUNET_TIME_timestamp_hton (dk->anchor_start); + /* Effective duration is based on denum->duration_withdraw + overlap, + but we may have shifted the 'anchor_end' to align them, thus the + only correct way to determine it is: */ + effective_duration = GNUNET_TIME_absolute_get_difference ( + dk->anchor_start.abs_time, + dk->anchor_end.abs_time); + an->duration_withdraw = GNUNET_TIME_relative_hton (effective_duration); + TALER_exchange_secmod_rsa_sign (&dk->h_rsa, denom->section, - dk->anchor, - denom->duration_withdraw, + dk->anchor_start, + effective_duration, &TES_smpriv, &an->secm_sig); an->secm_pub = TES_smpub; @@ -415,16 +428,28 @@ do_sign (const struct TALER_RsaPubHashP *h_rsa, GNUNET_h2s (&h_rsa->hash)); return TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN; } - if (GNUNET_TIME_absolute_is_future (dk->anchor.abs_time)) + if (GNUNET_TIME_absolute_is_future (dk->anchor_start.abs_time)) { /* it is too early */ GNUNET_assert (0 == pthread_mutex_unlock (&keys_lock)); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Signing request failed, denomination key %s is not yet valid (%llu)\n", GNUNET_h2s (&h_rsa->hash), - (unsigned long long) dk->anchor.abs_time.abs_value_us); + (unsigned long long) dk->anchor_start.abs_time.abs_value_us); return TALER_EC_EXCHANGE_DENOMINATION_HELPER_TOO_EARLY; } + if (GNUNET_TIME_absolute_is_past (dk->anchor_end.abs_time)) + { + /* it is too late; now, usually we should never get here + as we delete upon expiration, so this is just conservative */ + GNUNET_assert (0 == pthread_mutex_unlock (&keys_lock)); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Signing request failed, denomination key %s is expired (%llu)\n", + GNUNET_h2s (&h_rsa->hash), + (unsigned long long) dk->anchor_end.abs_time.abs_value_us); + /* usually we delete upon expiratoin, hence same EC */ + return TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN; + } GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Received request to sign over %u bytes with key %s\n", @@ -864,13 +889,15 @@ setup_key (struct DenominationKey *dk, &buf); GNUNET_CRYPTO_rsa_public_key_hash (pub, &dk->h_rsa.hash); - GNUNET_asprintf (&dk->filename, - "%s/%s/%llu", - keydir, - denom->section, - (unsigned long long) (dk->anchor.abs_time.abs_value_us - / GNUNET_TIME_UNIT_SECONDS.rel_value_us - )); + GNUNET_asprintf ( + &dk->filename, + "%s/%s/%llu-%llu", + keydir, + denom->section, + (unsigned long long) (dk->anchor_start.abs_time.abs_value_us + / GNUNET_TIME_UNIT_SECONDS.rel_value_us), + (unsigned long long) (dk->anchor_end.abs_time.abs_value_us + / GNUNET_TIME_UNIT_SECONDS.rel_value_us)); if (GNUNET_OK != GNUNET_DISK_fn_write (dk->filename, buf, @@ -890,7 +917,7 @@ setup_key (struct DenominationKey *dk, GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Setup fresh private key %s at %s in `%s' (generation #%llu)\n", GNUNET_h2s (&dk->h_rsa.hash), - GNUNET_TIME_timestamp2s (dk->anchor), + GNUNET_TIME_timestamp2s (dk->anchor_start), dk->filename, (unsigned long long) key_gen); dk->denom_priv = priv; @@ -989,7 +1016,8 @@ handle_revoke_request (struct TES_Client *client, denom = dk->denom; ndk = GNUNET_new (struct DenominationKey); ndk->denom = denom; - ndk->anchor = dk->anchor; + ndk->anchor_start = dk->anchor_start; + ndk->anchor_end = dk->anchor_end; if (GNUNET_OK != setup_key (ndk, dk)) @@ -1228,33 +1256,25 @@ rsa_update_client_keys (struct TES_Client *client) * Create a new denomination key (we do not have enough). * * @param[in] denom denomination key to create - * @param now current time to use (to get many keys to use the exact same time) + * @param anchor_start when to start key signing validity + * @param anchor_end when to end key signing validity * @return #GNUNET_OK on success */ static enum GNUNET_GenericReturnValue create_key (struct Denomination *denom, - struct GNUNET_TIME_Timestamp now) + struct GNUNET_TIME_Timestamp anchor_start, + struct GNUNET_TIME_Timestamp anchor_end) { struct DenominationKey *dk; - struct GNUNET_TIME_Timestamp anchor; - - anchor = now; - if (NULL != denom->keys_tail) - { - struct GNUNET_TIME_Absolute abs; - abs = GNUNET_TIME_absolute_add (denom->keys_tail->anchor.abs_time, - GNUNET_TIME_relative_subtract ( - denom->duration_withdraw, - overlap_duration)); - if (GNUNET_TIME_absolute_cmp (now.abs_time, - <, - abs)) - anchor = GNUNET_TIME_absolute_to_timestamp (abs); - } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Creating new key for `%s' with start date %s\n", + denom->section, + GNUNET_TIME_timestamp2s (anchor_start)); dk = GNUNET_new (struct DenominationKey); dk->denom = denom; - dk->anchor = anchor; + dk->anchor_start = anchor_start; + dk->anchor_end = anchor_end; if (GNUNET_OK != setup_key (dk, denom->keys_tail)) @@ -1270,95 +1290,57 @@ create_key (struct Denomination *denom, /** - * At what time does this denomination require its next action? - * Basically, the minimum of the withdraw expiration time of the - * oldest denomination key, and the withdraw expiration time of - * the newest denomination key minus the #lookahead_sign time. + * Obtain the maximum withdraw duration of all denominations. + * + * Must only be called while the #keys_lock is held. * - * @param denom denomination to compute action time for + * @return maximum withdraw duration, zero if there are no denominations + */ +static struct GNUNET_TIME_Relative +get_maximum_duration (void) +{ + struct GNUNET_TIME_Relative ret + = GNUNET_TIME_UNIT_ZERO; + + for (struct Denomination *denom = denom_head; + NULL != denom; + denom = denom->next) + { + ret = GNUNET_TIME_relative_max (ret, + denom->duration_withdraw); + } + return ret; +} + + +/** + * At what time do we need to next create keys if we just did? */ static struct GNUNET_TIME_Absolute -denomination_action_time (const struct Denomination *denom) +action_time () { - struct DenominationKey *head = denom->keys_head; - struct DenominationKey *tail = denom->keys_tail; - struct GNUNET_TIME_Absolute tt; - - if (NULL == head) - return GNUNET_TIME_UNIT_ZERO_ABS; - tt = GNUNET_TIME_absolute_subtract ( - GNUNET_TIME_absolute_subtract ( - GNUNET_TIME_absolute_add (tail->anchor.abs_time, - denom->duration_withdraw), - lookahead_sign), - overlap_duration); - if (head->rc > 0) - return tt; /* head expiration does not count due to rc > 0 */ - return GNUNET_TIME_absolute_min ( - GNUNET_TIME_absolute_add (head->anchor.abs_time, - denom->duration_withdraw), - tt); + struct GNUNET_TIME_Relative md = get_maximum_duration (); + struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); + uint64_t mod; + + mod = now.abs_value_us % md.rel_value_us; + now.abs_value_us -= mod; + return GNUNET_TIME_absolute_add (now, + md); } /** - * Create new keys and expire ancient keys of the given denomination @a denom. - * Removes the @a denom from the #denom_head DLL and re-insert its at the - * correct location sorted by next maintenance activity. + * Remove all denomination keys of @a denom that have expired. * - * @param[in,out] denom denomination to update material for - * @param now current time to use (to get many keys to use the exact same time) - * @param[in,out] wake set to true if we should wake the clients - * @return #GNUNET_OK on success + * @param[in,out] denom denomination family to remove keys for */ -static enum GNUNET_GenericReturnValue -update_keys (struct Denomination *denom, - struct GNUNET_TIME_Timestamp now, - bool *wake) +static void +remove_expired_denomination_keys (struct Denomination *denom) { - /* create new denomination keys */ - if (NULL != denom->keys_tail) - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Updating keys of denomination `%s', last key %s valid for another %s\n", - denom->section, - GNUNET_h2s (&denom->keys_tail->h_rsa.hash), - GNUNET_TIME_relative2s ( - GNUNET_TIME_absolute_get_remaining ( - GNUNET_TIME_absolute_subtract ( - GNUNET_TIME_absolute_add ( - denom->keys_tail->anchor.abs_time, - denom->duration_withdraw), - overlap_duration)), - GNUNET_YES)); - while ( (NULL == denom->keys_tail) || - GNUNET_TIME_absolute_is_past ( - GNUNET_TIME_absolute_subtract ( - GNUNET_TIME_absolute_subtract ( - GNUNET_TIME_absolute_add (denom->keys_tail->anchor.abs_time, - denom->duration_withdraw), - lookahead_sign), - overlap_duration)) ) - { - if (! *wake) - { - key_gen++; - *wake = true; - } - if (GNUNET_OK != - create_key (denom, - now)) - { - GNUNET_break (0); - globals->global_ret = EXIT_FAILURE; - GNUNET_SCHEDULER_shutdown (); - return GNUNET_SYSERR; - } - } - /* remove expired denomination keys */ while ( (NULL != denom->keys_head) && - GNUNET_TIME_absolute_is_past - (GNUNET_TIME_absolute_add (denom->keys_head->anchor.abs_time, - denom->duration_withdraw)) ) + GNUNET_TIME_absolute_is_past ( + denom->keys_head->anchor_end.abs_time)) { struct DenominationKey *key = denom->keys_head; struct DenominationKey *nxt = key->next; @@ -1385,72 +1367,155 @@ update_keys (struct Denomination *denom, GNUNET_free (key); key = nxt; } +} + + +/** + * Obtain the end anchor to use at this point. Uses the + * #lookahead_sign and then rounds it up by the maximum + * duration of any denomination to arrive at a globally + * valid end-date. + * + * Must only be called while the #keys_lock is held. + * + * @return end anchor + */ +static struct GNUNET_TIME_Timestamp +get_anchor_end (void) +{ + struct GNUNET_TIME_Relative md = get_maximum_duration (); + struct GNUNET_TIME_Absolute end + = GNUNET_TIME_relative_to_absolute (lookahead_sign); + uint64_t mod; + + /* Round up 'end' to a multiple of 'md' */ + mod = end.abs_value_us % md.rel_value_us; + end.abs_value_us -= mod; + return GNUNET_TIME_absolute_to_timestamp ( + GNUNET_TIME_absolute_add (end, + md)); +} + - /* Update position of 'denom' in #denom_head DLL: sort by action time */ +/** + * Create all denomination keys that are required for our + * desired lookahead and that we do not yet have. + * + * @param[in,out] opt our options + * @param[in,out] wake set to true if we should wake the clients + */ +static void +create_missing_keys (struct TALER_SECMOD_Options *opt, + bool *wake) +{ + struct GNUNET_TIME_Timestamp start; + struct GNUNET_TIME_Timestamp end; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Updating denominations ...\n"); + start = opt->global_now; + GNUNET_assert (0 == pthread_mutex_lock (&keys_lock)); + end = get_anchor_end (); + for (struct Denomination *denom = denom_head; + NULL != denom; + denom = denom->next) { - struct Denomination *before; - struct GNUNET_TIME_Absolute at; + struct GNUNET_TIME_Timestamp anchor_start; + struct GNUNET_TIME_Timestamp anchor_end; + struct GNUNET_TIME_Timestamp next_end; + bool finished = false; - at = denomination_action_time (denom); - GNUNET_CONTAINER_DLL_remove (denom_head, - denom_tail, - denom); - before = NULL; - for (struct Denomination *pos = denom_head; - NULL != pos; - pos = pos->next) + if (NULL != denom->keys_tail) { - if (GNUNET_TIME_absolute_cmp (denomination_action_time (pos), - >=, - at)) - break; - before = pos; + anchor_start = denom->keys_tail->anchor_end; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Expanding keys of denomination `%s', last key %s valid for another %s\n", + denom->section, + GNUNET_h2s (&denom->keys_tail->h_rsa.hash), + GNUNET_TIME_relative2s ( + GNUNET_TIME_absolute_get_remaining ( + anchor_start.abs_time), + true)); } - GNUNET_CONTAINER_DLL_insert_after (denom_head, - denom_tail, - before, - denom); + else + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Starting keys of denomination `%s'\n", + denom->section); + anchor_start = start; + } + finished = GNUNET_TIME_timestamp_cmp (anchor_start, + >=, + end); + while (! finished) + { + anchor_end = GNUNET_TIME_absolute_to_timestamp ( + GNUNET_TIME_absolute_add (anchor_start.abs_time, + denom->duration_withdraw)); + next_end = GNUNET_TIME_absolute_to_timestamp ( + GNUNET_TIME_absolute_add (anchor_end.abs_time, + denom->duration_withdraw)); + if (GNUNET_TIME_timestamp_cmp (next_end, + >, + end)) + { + anchor_end = end; /* extend period to align end periods */ + finished = true; + } + /* adjust start time down to ensure overlap */ + anchor_start = GNUNET_TIME_absolute_to_timestamp ( + GNUNET_TIME_absolute_subtract (anchor_start.abs_time, + overlap_duration)); + if (! *wake) + { + key_gen++; + *wake = true; + } + if (GNUNET_OK != + create_key (denom, + anchor_start, + anchor_end)) + { + GNUNET_break (0); + return; + } + anchor_start = anchor_end; + } + remove_expired_denomination_keys (denom); } - return GNUNET_OK; + GNUNET_assert (0 == pthread_mutex_unlock (&keys_lock)); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Updating denominations finished ...\n"); } /** * Task run periodically to expire keys and/or generate fresh ones. * - * @param cls NULL + * @param cls the `struct TALER_SECMOD_Options *` */ static void update_denominations (void *cls) { - struct Denomination *denom; - struct GNUNET_TIME_Absolute now; - struct GNUNET_TIME_Timestamp t; + struct TALER_SECMOD_Options *opt = cls; + struct GNUNET_TIME_Absolute at; bool wake = false; (void) cls; keygen_task = NULL; - now = GNUNET_TIME_absolute_get (); - t = GNUNET_TIME_absolute_to_timestamp (now); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Updating denominations ...\n"); - GNUNET_assert (0 == pthread_mutex_lock (&keys_lock)); - do { - denom = denom_head; - if (GNUNET_OK != - update_keys (denom, - t, - &wake)) - return; - } while (denom != denom_head); - GNUNET_assert (0 == pthread_mutex_unlock (&keys_lock)); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Updating denominations finished ...\n"); + /* update current time, global override no longer applies */ + opt->global_now = GNUNET_TIME_timestamp_get (); + create_missing_keys (opt, + &wake); if (wake) TES_wake_clients (); - keygen_task = GNUNET_SCHEDULER_add_at (denomination_action_time (denom), + at = action_time (); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Next key generation due at %s\n", + GNUNET_TIME_absolute2s (at)); + keygen_task = GNUNET_SCHEDULER_add_at (at, &update_denominations, - NULL); + opt); } @@ -1471,8 +1536,11 @@ parse_key (struct Denomination *denom, struct GNUNET_CRYPTO_RsaPrivateKey *priv; char *anchor_s; char dummy; - unsigned long long anchor_ll; - struct GNUNET_TIME_Timestamp anchor; + unsigned long long anchor_start_ll; + unsigned long long anchor_end_ll; + struct GNUNET_TIME_Timestamp anchor_start; + struct GNUNET_TIME_Timestamp anchor_end; + char *nf = NULL; anchor_s = strrchr (filename, '/'); @@ -1483,27 +1551,75 @@ parse_key (struct Denomination *denom, return; } anchor_s++; - if (1 != sscanf (anchor_s, - "%llu%c", - &anchor_ll, + if (2 != sscanf (anchor_s, + "%llu-%llu%c", + &anchor_start_ll, + &anchor_end_ll, &dummy)) { - /* Filenames in KEYDIR must ONLY be the anchor time in seconds! */ - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Filename `%s' invalid for key file, skipping\n", - filename); - return; + /* try legacy mode */ + if (1 != sscanf (anchor_s, + "%llu%c", + &anchor_start_ll, + &dummy)) + { + /* Filenames in KEYDIR must ONLY be the anchor time in seconds! */ + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Filename `%s' invalid for key file, skipping\n", + anchor_s); + return; + } + anchor_start.abs_time.abs_value_us + = anchor_start_ll * GNUNET_TIME_UNIT_SECONDS.rel_value_us; + if (anchor_start_ll != anchor_start.abs_time.abs_value_us + / GNUNET_TIME_UNIT_SECONDS.rel_value_us) + { + /* Integer overflow. Bad, invalid filename. */ + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Integer overflow. Filename `%s' invalid for key file, skipping\n", + anchor_s); + return; + } + anchor_end + = GNUNET_TIME_absolute_to_timestamp ( + GNUNET_TIME_absolute_add (anchor_start.abs_time, + denom->duration_withdraw)); + GNUNET_asprintf ( + &nf, + "%s/%s/%llu-%llu", + keydir, + denom->section, + anchor_start_ll, + (unsigned long long) (anchor_end.abs_time.abs_value_us + / GNUNET_TIME_UNIT_SECONDS.rel_value_us)); + /* Try to fix the legacy filename */ + if (0 != + rename (filename, + nf)) + { + GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, + "rename", + filename); + GNUNET_free (nf); + } } - anchor.abs_time.abs_value_us - = anchor_ll * GNUNET_TIME_UNIT_SECONDS.rel_value_us; - if (anchor_ll != anchor.abs_time.abs_value_us - / GNUNET_TIME_UNIT_SECONDS.rel_value_us) + else { - /* Integer overflow. Bad, invalid filename. */ - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Filename `%s' invalid for key file, skipping\n", - filename); - return; + anchor_start.abs_time.abs_value_us + = anchor_start_ll * GNUNET_TIME_UNIT_SECONDS.rel_value_us; + anchor_end.abs_time.abs_value_us + = anchor_end_ll * GNUNET_TIME_UNIT_SECONDS.rel_value_us; + if ( (anchor_start_ll != anchor_start.abs_time.abs_value_us + / GNUNET_TIME_UNIT_SECONDS.rel_value_us) || + (anchor_end_ll != anchor_end.abs_time.abs_value_us + / GNUNET_TIME_UNIT_SECONDS.rel_value_us) ) + { + /* Integer overflow. Bad, invalid filename. */ + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Integer overflow. Filename `%s' invalid for key file, skipping\n", + anchor_s); + return; + } } priv = GNUNET_CRYPTO_rsa_private_key_decode (buf, buf_size); @@ -1512,7 +1628,8 @@ parse_key (struct Denomination *denom, /* Parser failure. */ GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "File `%s' is malformed, skipping\n", - filename); + (NULL == nf) ? filename : nf); + GNUNET_free (nf); return; } @@ -1526,13 +1643,15 @@ parse_key (struct Denomination *denom, { GNUNET_break (0); GNUNET_CRYPTO_rsa_private_key_free (priv); + GNUNET_free (nf); return; } dk = GNUNET_new (struct DenominationKey); dk->denom_priv = priv; dk->denom = denom; - dk->anchor = anchor; - dk->filename = GNUNET_strdup (filename); + dk->anchor_start = anchor_start; + dk->anchor_end = anchor_end; + dk->filename = (NULL == nf) ? GNUNET_strdup (filename) : nf; GNUNET_CRYPTO_rsa_public_key_hash (pub, &dk->h_rsa.hash); dk->denom_pub = pub; @@ -1559,9 +1678,9 @@ parse_key (struct Denomination *denom, NULL != pos; pos = pos->next) { - if (GNUNET_TIME_timestamp_cmp (pos->anchor, + if (GNUNET_TIME_timestamp_cmp (pos->anchor_start, >, - anchor)) + anchor_start)) break; before = pos; } @@ -1728,6 +1847,17 @@ parse_denomination_cfg (const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_free (secname); return GNUNET_SYSERR; } + if (GNUNET_TIME_relative_cmp (denom->duration_withdraw, + <, + GNUNET_TIME_UNIT_SECONDS)) + { + GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, + ct, + "DURATION_WITHDRAW", + "less than one second is not supported"); + GNUNET_free (secname); + return GNUNET_SYSERR; + } if (GNUNET_TIME_relative_cmp (overlap_duration, >=, denom->duration_withdraw)) @@ -1786,11 +1916,6 @@ struct LoadContext const char *cprefix; /** - * Current time to use. - */ - struct GNUNET_TIME_Timestamp t; - - /** * Status, to be set to #GNUNET_SYSERR on failure */ enum GNUNET_GenericReturnValue ret; @@ -1810,7 +1935,6 @@ load_denominations (void *cls, { struct LoadContext *ctx = cls; struct Denomination *denom; - bool wake = true; char *cipher; if (0 != strncasecmp (denomination_alias, @@ -1828,7 +1952,8 @@ load_denominations (void *cls, "CIPHER"); return; } - if (0 != strcmp (cipher, "RSA")) + if (0 != strcmp (cipher, + "RSA")) { GNUNET_free (cipher); return; /* Ignore denominations of other types than CS */ @@ -1864,9 +1989,6 @@ load_denominations (void *cls, GNUNET_CONTAINER_DLL_insert (denom_head, denom_tail, denom); - update_keys (denom, - ctx->t, - &wake); } @@ -2019,9 +2141,9 @@ TALER_SECMOD_rsa_run (void *cls, struct LoadContext lc = { .cfg = cfg, .ret = GNUNET_OK, - .t = opt->global_now, .cprefix = opt->cprefix }; + bool wake = true; GNUNET_assert (0 == pthread_mutex_lock (&keys_lock)); GNUNET_CONFIGURATION_iterate_sections (cfg, @@ -2034,6 +2156,8 @@ TALER_SECMOD_rsa_run (void *cls, GNUNET_SCHEDULER_shutdown (); return; } + create_missing_keys (opt, + &wake); } if (NULL == denom_head) { @@ -2048,5 +2172,5 @@ TALER_SECMOD_rsa_run (void *cls, keygen_task = GNUNET_SCHEDULER_add_with_priority ( GNUNET_SCHEDULER_PRIORITY_URGENT, &update_denominations, - NULL); + opt); } diff --git a/src/util/test_helper_cs.conf b/src/util/test_helper_cs.conf @@ -1,6 +1,6 @@ [PATHS] # Persistent data storage for the testcase -TALER_TEST_HOME = test_helper_cs_home/ +TALER_TEST_HOME = test_helper_cs_home [coin_1] DURATION_WITHDRAW = 1 minute diff --git a/src/util/test_helper_rsa.c b/src/util/test_helper_rsa.c @@ -931,6 +931,7 @@ int main (int argc, const char *const argv[]) { + const char *loglevel = "WARNING"; struct GNUNET_OS_Process *helper; char *libexec_dir; char *binary_name; @@ -943,7 +944,7 @@ main (int argc, unsetenv ("XDG_DATA_HOME"); unsetenv ("XDG_CONFIG_HOME"); GNUNET_log_setup ("test-helper-rsa", - "WARNING", + loglevel, NULL); libexec_dir = GNUNET_OS_installation_get_path (TALER_EXCHANGE_project_data (), GNUNET_OS_IPK_BINDIR); @@ -959,7 +960,7 @@ main (int argc, "-c", "test_helper_rsa.conf", "-L", - "WARNING", + loglevel, NULL); if (NULL == helper) { diff --git a/src/util/test_helper_rsa.conf b/src/util/test_helper_rsa.conf @@ -1,6 +1,6 @@ [PATHS] # Persistent data storage for the testcase -TALER_TEST_HOME = test_helper_rsa_home/ +TALER_TEST_HOME = test_helper_rsa_home [coin_1] DURATION_WITHDRAW = 1 minute