exchange

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

secmod_rsa.c (60528B)


      1 /*
      2   This file is part of TALER
      3   Copyright (C) 2014-2026 Taler Systems SA
      4 
      5   TALER is free software; you can redistribute it and/or modify it under the
      6   terms of the GNU General Public License as published by the Free Software
      7   Foundation; either version 3, or (at your option) any later version.
      8 
      9   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
     10   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     11   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
     12 
     13   You should have received a copy of the GNU General Public License along with
     14   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     15 */
     16 /**
     17  * @file util/secmod_rsa.c
     18  * @brief Standalone process to perform private key RSA operations
     19  * @author Christian Grothoff
     20  *
     21  * Key design points:
     22  * - EVERY thread of the exchange will have its own pair of connections to the
     23  *   crypto helpers.  This way, every thread will also have its own /keys state
     24  *   and avoid the need to synchronize on those.
     25  * - auditor signatures and master signatures are to be kept in the exchange DB,
     26  *   and merged with the public keys of the helper by the exchange HTTPD!
     27  * - the main loop of the helper is SINGLE-THREADED, but there are
     28  *   threads for crypto-workers which do the signing in parallel, one per client.
     29  * - thread-safety: signing happens in parallel, thus when REMOVING private keys,
     30  *   we must ensure that all signers are done before we fully free() the
     31  *   private key. This is done by reference counting (as work is always
     32  *   assigned and collected by the main thread).
     33  */
     34 #include "platform.h"
     35 #include "taler/taler_util.h"
     36 #include "secmod_rsa.h"
     37 #include <gcrypt.h>
     38 #include <pthread.h>
     39 #include "taler/taler_error_codes.h"
     40 #include "taler/taler_signatures.h"
     41 #include "secmod_common.h"
     42 #include <poll.h>
     43 
     44 
     45 /**
     46  * Information we keep per denomination.
     47  */
     48 struct Denomination;
     49 
     50 
     51 /**
     52  * One particular denomination key.
     53  */
     54 struct DenominationKey
     55 {
     56 
     57   /**
     58    * Kept in a DLL of the respective denomination. Sorted by anchor time.
     59    */
     60   struct DenominationKey *next;
     61 
     62   /**
     63    * Kept in a DLL of the respective denomination. Sorted by anchor time.
     64    */
     65   struct DenominationKey *prev;
     66 
     67   /**
     68    * Denomination this key belongs to.
     69    */
     70   struct Denomination *denom;
     71 
     72   /**
     73    * Name of the file this key is stored under.
     74    */
     75   char *filename;
     76 
     77   /**
     78    * The private key of the denomination.
     79    */
     80   struct GNUNET_CRYPTO_RsaPrivateKey *denom_priv;
     81 
     82   /**
     83    * The public key of the denomination.
     84    */
     85   struct GNUNET_CRYPTO_RsaPublicKey *denom_pub;
     86 
     87   /**
     88    * Message to transmit to clients to introduce this public key.
     89    */
     90   struct TALER_CRYPTO_RsaKeyAvailableNotification *an;
     91 
     92   /**
     93    * Hash of this denomination's public key.
     94    */
     95   struct TALER_RsaPubHashP h_rsa;
     96 
     97   /**
     98    * Time at which this key is supposed to become valid.
     99    */
    100   struct GNUNET_TIME_Timestamp anchor_start;
    101 
    102   /**
    103    * Time at which this key is supposed to expire (exclusive).
    104    */
    105   struct GNUNET_TIME_Timestamp anchor_end;
    106 
    107   /**
    108    * Generation when this key was created or revoked.
    109    */
    110   uint64_t key_gen;
    111 
    112   /**
    113    * Reference counter. Counts the number of threads that are
    114    * using this key at this time.
    115    */
    116   unsigned int rc;
    117 
    118   /**
    119    * Flag set to true if this key has been purged and the memory
    120    * must be freed as soon as @e rc hits zero.
    121    */
    122   bool purge;
    123 
    124 };
    125 
    126 
    127 struct Denomination
    128 {
    129 
    130   /**
    131    * Kept in a DLL.
    132    */
    133   struct Denomination *next;
    134 
    135   /**
    136    * Kept in a DLL.
    137    */
    138   struct Denomination *prev;
    139 
    140   /**
    141    * Head of DLL of actual keys of this denomination.
    142    */
    143   struct DenominationKey *keys_head;
    144 
    145   /**
    146    * Tail of DLL of actual keys of this denomination.
    147    */
    148   struct DenominationKey *keys_tail;
    149 
    150   /**
    151    * How long can coins be withdrawn (generated)?  Should be small
    152    * enough to limit how many coins will be signed into existence with
    153    * the same key, but large enough to still provide a reasonable
    154    * anonymity set.
    155    */
    156   struct GNUNET_TIME_Relative duration_withdraw;
    157 
    158   /**
    159    * What is the configuration section of this denomination type?  Also used
    160    * for the directory name where the denomination keys are stored.
    161    */
    162   char *section;
    163 
    164   /**
    165    * Length of (new) RSA keys (in bits).
    166    */
    167   uint32_t rsa_keysize;
    168 };
    169 
    170 
    171 /**
    172  * A semaphore.
    173  */
    174 struct Semaphore
    175 {
    176   /**
    177    * Mutex for the semaphore.
    178    */
    179   pthread_mutex_t mutex;
    180 
    181   /**
    182    * Condition variable for the semaphore.
    183    */
    184   pthread_cond_t cv;
    185 
    186   /**
    187    * Counter of the semaphore.
    188    */
    189   unsigned int ctr;
    190 };
    191 
    192 
    193 /**
    194  * Job in a batch sign request.
    195  */
    196 struct BatchJob;
    197 
    198 /**
    199  * Handle for a thread that does work in batch signing.
    200  */
    201 struct Worker
    202 {
    203   /**
    204    * Kept in a DLL.
    205    */
    206   struct Worker *prev;
    207 
    208   /**
    209    * Kept in a DLL.
    210    */
    211   struct Worker *next;
    212 
    213   /**
    214    * Job this worker should do next.
    215    */
    216   struct BatchJob *job;
    217 
    218   /**
    219    * Semaphore to signal the worker that a job is available.
    220    */
    221   struct Semaphore sem;
    222 
    223   /**
    224    * Handle for this thread.
    225    */
    226   pthread_t pt;
    227 
    228   /**
    229    * Set to true if the worker should terminate.
    230    */
    231   bool do_shutdown;
    232 };
    233 
    234 
    235 /**
    236  * Job in a batch sign request.
    237  */
    238 struct BatchJob
    239 {
    240   /**
    241    * Request we are working on.
    242    */
    243   const struct TALER_CRYPTO_SignRequest *sr;
    244 
    245   /**
    246    * Thread doing the work.
    247    */
    248   struct Worker *worker;
    249 
    250   /**
    251    * Result with the signature.
    252    */
    253   struct GNUNET_CRYPTO_RsaSignature *rsa_signature;
    254 
    255   /**
    256    * Semaphore to signal that the job is finished.
    257    */
    258   struct Semaphore sem;
    259 
    260   /**
    261    * Computation status.
    262    */
    263   enum TALER_ErrorCode ec;
    264 
    265 };
    266 
    267 
    268 /**
    269  * Head of DLL of workers ready for more work.
    270  */
    271 static struct Worker *worker_head;
    272 
    273 /**
    274  * Tail of DLL of workers ready for more work.
    275  */
    276 static struct Worker *worker_tail;
    277 
    278 /**
    279  * Lock for manipulating the worker DLL.
    280  */
    281 static pthread_mutex_t worker_lock;
    282 
    283 /**
    284  * Total number of workers that were started.
    285  */
    286 static unsigned int workers;
    287 
    288 /**
    289  * Semaphore used to grab a worker.
    290  */
    291 static struct Semaphore worker_sem;
    292 
    293 /**
    294  * Command-line options for various TALER_SECMOD_XXX_run() functions.
    295  */
    296 static struct TALER_SECMOD_Options *globals;
    297 
    298 /**
    299  * Where do we store the keys?
    300  */
    301 static char *keydir;
    302 
    303 /**
    304  * How much should coin creation (@e duration_withdraw) duration overlap
    305  * with the next denomination?  Basically, the starting time of two
    306  * denominations is always @e duration_withdraw - #overlap_duration apart.
    307  */
    308 static struct GNUNET_TIME_Relative overlap_duration;
    309 
    310 /**
    311  * How long into the future do we pre-generate keys?
    312  */
    313 static struct GNUNET_TIME_Relative lookahead_sign;
    314 
    315 /**
    316  * All of our denominations, in a DLL. Sorted?
    317  */
    318 static struct Denomination *denom_head;
    319 
    320 /**
    321  * All of our denominations, in a DLL. Sorted?
    322  */
    323 static struct Denomination *denom_tail;
    324 
    325 /**
    326  * Map of hashes of public (RSA) keys to `struct DenominationKey *`
    327  * with the respective private keys.
    328  */
    329 static struct GNUNET_CONTAINER_MultiHashMap *keys;
    330 
    331 /**
    332  * Task run to generate new keys.
    333  */
    334 static struct GNUNET_SCHEDULER_Task *keygen_task;
    335 
    336 /**
    337  * Lock for the keys queue.
    338  */
    339 static pthread_mutex_t keys_lock;
    340 
    341 /**
    342  * Current key generation.
    343  */
    344 static uint64_t key_gen;
    345 
    346 
    347 /**
    348  * Generate the announcement message for @a dk.
    349  *
    350  * @param[in,out] dk denomination key to generate the announcement for
    351  */
    352 static void
    353 generate_response (struct DenominationKey *dk)
    354 {
    355   struct Denomination *denom = dk->denom;
    356   size_t nlen = strlen (denom->section) + 1;
    357   struct TALER_CRYPTO_RsaKeyAvailableNotification *an;
    358   size_t buf_len;
    359   void *buf;
    360   void *p;
    361   size_t tlen;
    362   struct GNUNET_TIME_Relative effective_duration;
    363 
    364   buf_len = GNUNET_CRYPTO_rsa_public_key_encode (dk->denom_pub,
    365                                                  &buf);
    366   GNUNET_assert (buf_len < UINT16_MAX);
    367   GNUNET_assert (nlen < UINT16_MAX);
    368   tlen = buf_len + nlen + sizeof (*an);
    369   GNUNET_assert (tlen < UINT16_MAX);
    370   an = GNUNET_malloc (tlen);
    371   an->header.size = htons ((uint16_t) tlen);
    372   an->header.type = htons (TALER_HELPER_RSA_MT_AVAIL);
    373   an->pub_size = htons ((uint16_t) buf_len);
    374   an->section_name_len = htons ((uint16_t) nlen);
    375   an->anchor_time = GNUNET_TIME_timestamp_hton (dk->anchor_start);
    376   /* Effective duration is based on denum->duration_withdraw + overlap,
    377      but we may have shifted the 'anchor_end' to align them, thus the
    378      only correct way to determine it is: */
    379   effective_duration = GNUNET_TIME_absolute_get_difference (
    380     dk->anchor_start.abs_time,
    381     dk->anchor_end.abs_time);
    382   an->duration_withdraw = GNUNET_TIME_relative_hton (effective_duration);
    383 
    384   TALER_exchange_secmod_rsa_sign (&dk->h_rsa,
    385                                   denom->section,
    386                                   dk->anchor_start,
    387                                   effective_duration,
    388                                   &TES_smpriv,
    389                                   &an->secm_sig);
    390   an->secm_pub = TES_smpub;
    391   p = (void *) &an[1];
    392   GNUNET_memcpy (p,
    393                  buf,
    394                  buf_len);
    395   GNUNET_free (buf);
    396   GNUNET_memcpy (p + buf_len,
    397                  denom->section,
    398                  nlen);
    399   dk->an = an;
    400 }
    401 
    402 
    403 /**
    404  * Do the actual signing work.
    405  *
    406  * @param h_rsa key to sign with
    407  * @param bm blinded message to sign
    408  * @param[out] rsa_signaturep set to the RSA signature
    409  * @return #TALER_EC_NONE on success
    410  */
    411 static enum TALER_ErrorCode
    412 do_sign (const struct TALER_RsaPubHashP *h_rsa,
    413          const struct GNUNET_CRYPTO_RsaBlindedMessage *bm,
    414          struct GNUNET_CRYPTO_RsaSignature **rsa_signaturep)
    415 {
    416   struct DenominationKey *dk;
    417   struct GNUNET_CRYPTO_RsaSignature *rsa_signature;
    418   struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
    419 
    420   GNUNET_assert (0 == pthread_mutex_lock (&keys_lock));
    421   dk = GNUNET_CONTAINER_multihashmap_get (keys,
    422                                           &h_rsa->hash);
    423   if (NULL == dk)
    424   {
    425     GNUNET_assert (0 == pthread_mutex_unlock (&keys_lock));
    426     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    427                 "Signing request failed, denomination key %s unknown\n",
    428                 GNUNET_h2s (&h_rsa->hash));
    429     return TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN;
    430   }
    431   if (GNUNET_TIME_absolute_is_future (dk->anchor_start.abs_time))
    432   {
    433     /* it is too early */
    434     GNUNET_assert (0 == pthread_mutex_unlock (&keys_lock));
    435     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    436                 "Signing request failed, denomination key %s is not yet valid (%llu)\n",
    437                 GNUNET_h2s (&h_rsa->hash),
    438                 (unsigned long long) dk->anchor_start.abs_time.abs_value_us);
    439     return TALER_EC_EXCHANGE_DENOMINATION_HELPER_TOO_EARLY;
    440   }
    441   if (GNUNET_TIME_absolute_is_past (dk->anchor_end.abs_time))
    442   {
    443     /* it is too late; now, usually we should never get here
    444        as we delete upon expiration, so this is just conservative */
    445     GNUNET_assert (0 == pthread_mutex_unlock (&keys_lock));
    446     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    447                 "Signing request failed, denomination key %s is expired (%llu)\n",
    448                 GNUNET_h2s (&h_rsa->hash),
    449                 (unsigned long long) dk->anchor_end.abs_time.abs_value_us);
    450     /* usually we delete upon expiratoin, hence same EC */
    451     return TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN;
    452   }
    453 
    454   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    455               "Received request to sign over %u bytes with key %s\n",
    456               (unsigned int) bm->blinded_msg_size,
    457               GNUNET_h2s (&h_rsa->hash));
    458   GNUNET_assert (dk->rc < UINT_MAX);
    459   dk->rc++;
    460   GNUNET_assert (0 == pthread_mutex_unlock (&keys_lock));
    461   rsa_signature
    462     = GNUNET_CRYPTO_rsa_sign_blinded (dk->denom_priv,
    463                                       bm);
    464   GNUNET_assert (0 == pthread_mutex_lock (&keys_lock));
    465   GNUNET_assert (dk->rc > 0);
    466   dk->rc--;
    467   GNUNET_assert (0 == pthread_mutex_unlock (&keys_lock));
    468   if (NULL == rsa_signature)
    469   {
    470     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
    471                 "Signing request failed, worker failed to produce signature\n");
    472     return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE;
    473   }
    474 
    475   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    476               "Sending RSA signature after %s\n",
    477               GNUNET_TIME_relative2s (
    478                 GNUNET_TIME_absolute_get_duration (now),
    479                 GNUNET_YES));
    480   *rsa_signaturep = rsa_signature;
    481   return TALER_EC_NONE;
    482 }
    483 
    484 
    485 /**
    486  * Generate error response that signing failed.
    487  *
    488  * @param client client to send response to
    489  * @param ec error code to include
    490  * @return #GNUNET_OK on success
    491  */
    492 static enum GNUNET_GenericReturnValue
    493 fail_sign (struct TES_Client *client,
    494            enum TALER_ErrorCode ec)
    495 {
    496   struct TALER_CRYPTO_SignFailure sf = {
    497     .header.size = htons (sizeof (sf)),
    498     .header.type = htons (TALER_HELPER_RSA_MT_RES_SIGN_FAILURE),
    499     .ec = htonl (ec)
    500   };
    501 
    502   return TES_transmit (client->csock,
    503                        &sf.header);
    504 }
    505 
    506 
    507 /**
    508  * Generate signature response.
    509  *
    510  * @param client client to send response to
    511  * @param[in] rsa_signature signature to send, freed by this function
    512  * @return #GNUNET_OK on success
    513  */
    514 static enum GNUNET_GenericReturnValue
    515 send_signature (struct TES_Client *client,
    516                 struct GNUNET_CRYPTO_RsaSignature *rsa_signature)
    517 {
    518   struct TALER_CRYPTO_SignResponse *sr;
    519   void *buf;
    520   size_t buf_size;
    521   size_t tsize;
    522   enum GNUNET_GenericReturnValue ret;
    523 
    524   buf_size = GNUNET_CRYPTO_rsa_signature_encode (rsa_signature,
    525                                                  &buf);
    526   GNUNET_CRYPTO_rsa_signature_free (rsa_signature);
    527   tsize = sizeof (*sr) + buf_size;
    528   GNUNET_assert (tsize < UINT16_MAX);
    529   sr = GNUNET_malloc (tsize);
    530   sr->header.size = htons (tsize);
    531   sr->header.type = htons (TALER_HELPER_RSA_MT_RES_SIGNATURE);
    532   GNUNET_memcpy (&sr[1],
    533                  buf,
    534                  buf_size);
    535   GNUNET_free (buf);
    536   ret = TES_transmit (client->csock,
    537                       &sr->header);
    538   GNUNET_free (sr);
    539   return ret;
    540 }
    541 
    542 
    543 /**
    544  * Handle @a client request @a sr to create signature. Create the
    545  * signature using the respective key and return the result to
    546  * the client.
    547  *
    548  * @param client the client making the request
    549  * @param sr the request details
    550  * @return #GNUNET_OK on success
    551  */
    552 static enum GNUNET_GenericReturnValue
    553 handle_sign_request (struct TES_Client *client,
    554                      const struct TALER_CRYPTO_SignRequest *sr)
    555 {
    556   struct GNUNET_CRYPTO_RsaBlindedMessage bm = {
    557     .blinded_msg = (void *) &sr[1],
    558     .blinded_msg_size = ntohs (sr->header.size) - sizeof (*sr)
    559   };
    560   struct GNUNET_CRYPTO_RsaSignature *rsa_signature;
    561   enum TALER_ErrorCode ec;
    562 
    563   ec = do_sign (&sr->h_rsa,
    564                 &bm,
    565                 &rsa_signature);
    566   if (TALER_EC_NONE != ec)
    567   {
    568     return fail_sign (client,
    569                       ec);
    570   }
    571   return send_signature (client,
    572                          rsa_signature);
    573 }
    574 
    575 
    576 /**
    577  * Initialize a semaphore @a sem with a value of @a val.
    578  *
    579  * @param[out] sem semaphore to initialize
    580  * @param val initial value of the semaphore
    581  */
    582 static void
    583 sem_init (struct Semaphore *sem,
    584           unsigned int val)
    585 {
    586   GNUNET_assert (0 ==
    587                  pthread_mutex_init (&sem->mutex,
    588                                      NULL));
    589   GNUNET_assert (0 ==
    590                  pthread_cond_init (&sem->cv,
    591                                     NULL));
    592   sem->ctr = val;
    593 }
    594 
    595 
    596 /**
    597  * Decrement semaphore, blocks until this is possible.
    598  *
    599  * @param[in,out] sem semaphore to decrement
    600  */
    601 static void
    602 sem_down (struct Semaphore *sem)
    603 {
    604   GNUNET_assert (0 == pthread_mutex_lock (&sem->mutex));
    605   while (0 == sem->ctr)
    606   {
    607     pthread_cond_wait (&sem->cv,
    608                        &sem->mutex);
    609   }
    610   sem->ctr--;
    611   GNUNET_assert (0 == pthread_mutex_unlock (&sem->mutex));
    612 }
    613 
    614 
    615 /**
    616  * Increment semaphore, blocks until this is possible.
    617  *
    618  * @param[in,out] sem semaphore to decrement
    619  */
    620 static void
    621 sem_up (struct Semaphore *sem)
    622 {
    623   GNUNET_assert (0 == pthread_mutex_lock (&sem->mutex));
    624   sem->ctr++;
    625   GNUNET_assert (0 == pthread_mutex_unlock (&sem->mutex));
    626   pthread_cond_signal (&sem->cv);
    627 }
    628 
    629 
    630 /**
    631  * Release resources used by @a sem.
    632  *
    633  * @param[in] sem semaphore to release (except the memory itself)
    634  */
    635 static void
    636 sem_done (struct Semaphore *sem)
    637 {
    638   GNUNET_break (0 == pthread_cond_destroy (&sem->cv));
    639   GNUNET_break (0 == pthread_mutex_destroy (&sem->mutex));
    640 }
    641 
    642 
    643 /**
    644  * Main logic of a worker thread. Grabs work, does it,
    645  * grabs more work.
    646  *
    647  * @param cls a `struct Worker *`
    648  * @returns cls
    649  */
    650 static void *
    651 worker (void *cls)
    652 {
    653   struct Worker *w = cls;
    654 
    655   while (true)
    656   {
    657     GNUNET_assert (0 == pthread_mutex_lock (&worker_lock));
    658     GNUNET_CONTAINER_DLL_insert (worker_head,
    659                                  worker_tail,
    660                                  w);
    661     GNUNET_assert (0 == pthread_mutex_unlock (&worker_lock));
    662     sem_up (&worker_sem);
    663     sem_down (&w->sem);
    664     if (w->do_shutdown)
    665       break;
    666     {
    667       struct BatchJob *bj = w->job;
    668       const struct TALER_CRYPTO_SignRequest *sr = bj->sr;
    669       struct GNUNET_CRYPTO_RsaBlindedMessage bm = {
    670         .blinded_msg = (void *) &sr[1],
    671         .blinded_msg_size = ntohs (sr->header.size) - sizeof (*sr)
    672       };
    673 
    674       bj->ec = do_sign (&sr->h_rsa,
    675                         &bm,
    676                         &bj->rsa_signature);
    677       sem_up (&bj->sem);
    678       w->job = NULL;
    679     }
    680   }
    681   return w;
    682 }
    683 
    684 
    685 /**
    686  * Start batch job @a bj to sign @a sr.
    687  *
    688  * @param sr signature request to answer
    689  * @param[out] bj job data structure
    690  */
    691 static void
    692 start_job (const struct TALER_CRYPTO_SignRequest *sr,
    693            struct BatchJob *bj)
    694 {
    695   sem_init (&bj->sem,
    696             0);
    697   bj->sr = sr;
    698   sem_down (&worker_sem);
    699   GNUNET_assert (0 == pthread_mutex_lock (&worker_lock));
    700   bj->worker = worker_head;
    701   GNUNET_CONTAINER_DLL_remove (worker_head,
    702                                worker_tail,
    703                                bj->worker);
    704   GNUNET_assert (0 == pthread_mutex_unlock (&worker_lock));
    705   bj->worker->job = bj;
    706   sem_up (&bj->worker->sem);
    707 }
    708 
    709 
    710 /**
    711  * Finish a job @a bj for a @a client.
    712  *
    713  * @param client who made the request
    714  * @param[in,out] bj job to finish
    715  */
    716 static void
    717 finish_job (struct TES_Client *client,
    718             struct BatchJob *bj)
    719 {
    720   sem_down (&bj->sem);
    721   sem_done (&bj->sem);
    722   if (TALER_EC_NONE != bj->ec)
    723   {
    724     fail_sign (client,
    725                bj->ec);
    726     return;
    727   }
    728   GNUNET_assert (NULL != bj->rsa_signature);
    729   send_signature (client,
    730                   bj->rsa_signature);
    731   bj->rsa_signature = NULL; /* freed in send_signature */
    732 }
    733 
    734 
    735 /**
    736  * Handle @a client request @a sr to create a batch of signature. Creates the
    737  * signatures using the respective key and return the results to the client.
    738  *
    739  * @param client the client making the request
    740  * @param bsr the request details
    741  * @return #GNUNET_OK on success
    742  */
    743 static enum GNUNET_GenericReturnValue
    744 handle_batch_sign_request (struct TES_Client *client,
    745                            const struct TALER_CRYPTO_BatchSignRequest *bsr)
    746 {
    747   uint32_t bs = ntohl (bsr->batch_size);
    748   uint16_t size = ntohs (bsr->header.size) - sizeof (*bsr);
    749   const void *off = (const void *) &bsr[1];
    750   unsigned int idx = 0;
    751   struct BatchJob jobs[bs];
    752   bool failure = false;
    753 
    754   if (bs > TALER_MAX_COINS)
    755   {
    756     GNUNET_break_op (0);
    757     return GNUNET_SYSERR;
    758   }
    759   while ( (idx < bs) &&
    760           (size > sizeof (struct TALER_CRYPTO_SignRequest)) )
    761   {
    762     const struct TALER_CRYPTO_SignRequest *sr = off;
    763     uint16_t s = ntohs (sr->header.size);
    764 
    765     if ( (s > size) ||
    766          (s < sizeof (*sr)) )
    767     {
    768       failure = true;
    769       bs = idx;
    770       break;
    771     }
    772     start_job (sr,
    773                &jobs[idx++]);
    774     off += s;
    775     size -= s;
    776   }
    777   GNUNET_break_op (0 == size);
    778   bs = GNUNET_MIN (bs,
    779                    idx);
    780   for (unsigned int i = 0; i<bs; i++)
    781     finish_job (client,
    782                 &jobs[i]);
    783   if (failure)
    784   {
    785     struct TALER_CRYPTO_SignFailure sf = {
    786       .header.size = htons (sizeof (sf)),
    787       .header.type = htons (TALER_HELPER_RSA_MT_RES_BATCH_FAILURE),
    788       .ec = htonl (TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE)
    789     };
    790 
    791     GNUNET_break (0);
    792     return TES_transmit (client->csock,
    793                          &sf.header);
    794   }
    795   return GNUNET_OK;
    796 }
    797 
    798 
    799 /**
    800  * Start worker thread for batch processing.
    801  *
    802  * @return #GNUNET_OK on success
    803  */
    804 static enum GNUNET_GenericReturnValue
    805 start_worker (void)
    806 {
    807   struct Worker *w;
    808 
    809   w = GNUNET_new (struct Worker);
    810   sem_init (&w->sem,
    811             0);
    812   if (0 != pthread_create (&w->pt,
    813                            NULL,
    814                            &worker,
    815                            w))
    816   {
    817     GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
    818                          "pthread_create");
    819     GNUNET_free (w);
    820     return GNUNET_SYSERR;
    821   }
    822   workers++;
    823   return GNUNET_OK;
    824 }
    825 
    826 
    827 /**
    828  * Stop all worker threads.
    829  */
    830 static void
    831 stop_workers (void)
    832 {
    833   while (workers > 0)
    834   {
    835     struct Worker *w;
    836     void *result;
    837 
    838     sem_down (&worker_sem);
    839     GNUNET_assert (0 == pthread_mutex_lock (&worker_lock));
    840     w = worker_head;
    841     GNUNET_CONTAINER_DLL_remove (worker_head,
    842                                  worker_tail,
    843                                  w);
    844     GNUNET_assert (0 == pthread_mutex_unlock (&worker_lock));
    845     w->do_shutdown = true;
    846     sem_up (&w->sem);
    847     pthread_join (w->pt,
    848                   &result);
    849     GNUNET_assert (result == w);
    850     sem_done (&w->sem);
    851     GNUNET_free (w);
    852     workers--;
    853   }
    854 }
    855 
    856 
    857 /**
    858  * Initialize key material for denomination key @a dk (also on disk).
    859  *
    860  * @param[in,out] dk denomination key to compute key material for
    861  * @param position where in the DLL will the @a dk go
    862  * @return #GNUNET_OK on success
    863  */
    864 static enum GNUNET_GenericReturnValue
    865 setup_key (struct DenominationKey *dk,
    866            struct DenominationKey *position)
    867 {
    868   struct Denomination *denom = dk->denom;
    869   struct GNUNET_CRYPTO_RsaPrivateKey *priv;
    870   struct GNUNET_CRYPTO_RsaPublicKey *pub;
    871   size_t buf_size;
    872   void *buf;
    873 
    874   priv = GNUNET_CRYPTO_rsa_private_key_create (denom->rsa_keysize);
    875   if (NULL == priv)
    876   {
    877     GNUNET_break (0);
    878     GNUNET_SCHEDULER_shutdown ();
    879     globals->global_ret = EXIT_FAILURE;
    880     return GNUNET_SYSERR;
    881   }
    882   pub = GNUNET_CRYPTO_rsa_private_key_get_public (priv);
    883   if (NULL == pub)
    884   {
    885     GNUNET_break (0);
    886     GNUNET_CRYPTO_rsa_private_key_free (priv);
    887     return GNUNET_SYSERR;
    888   }
    889   buf_size = GNUNET_CRYPTO_rsa_private_key_encode (priv,
    890                                                    &buf);
    891   GNUNET_CRYPTO_rsa_public_key_hash (pub,
    892                                      &dk->h_rsa.hash);
    893   GNUNET_asprintf (
    894     &dk->filename,
    895     "%s/%s/%llu-%llu",
    896     keydir,
    897     denom->section,
    898     (unsigned long long) (dk->anchor_start.abs_time.abs_value_us
    899                           / GNUNET_TIME_UNIT_SECONDS.rel_value_us),
    900     (unsigned long long) (dk->anchor_end.abs_time.abs_value_us
    901                           / GNUNET_TIME_UNIT_SECONDS.rel_value_us));
    902   if (GNUNET_OK !=
    903       GNUNET_DISK_fn_write (dk->filename,
    904                             buf,
    905                             buf_size,
    906                             GNUNET_DISK_PERM_USER_READ))
    907   {
    908     GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
    909                               "write",
    910                               dk->filename);
    911     GNUNET_free (dk->filename);
    912     GNUNET_free (buf);
    913     GNUNET_CRYPTO_rsa_private_key_free (priv);
    914     GNUNET_CRYPTO_rsa_public_key_free (pub);
    915     return GNUNET_SYSERR;
    916   }
    917   GNUNET_free (buf);
    918   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    919               "Setup fresh private key %s at %s in `%s' (generation #%llu)\n",
    920               GNUNET_h2s (&dk->h_rsa.hash),
    921               GNUNET_TIME_timestamp2s (dk->anchor_start),
    922               dk->filename,
    923               (unsigned long long) key_gen);
    924   dk->denom_priv = priv;
    925   dk->denom_pub = pub;
    926   dk->key_gen = key_gen;
    927   generate_response (dk);
    928   if (GNUNET_OK !=
    929       GNUNET_CONTAINER_multihashmap_put (
    930         keys,
    931         &dk->h_rsa.hash,
    932         dk,
    933         GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
    934   {
    935     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    936                 "Duplicate private key created! Terminating.\n");
    937     GNUNET_CRYPTO_rsa_private_key_free (dk->denom_priv);
    938     GNUNET_CRYPTO_rsa_public_key_free (dk->denom_pub);
    939     GNUNET_free (dk->filename);
    940     GNUNET_free (dk->an);
    941     GNUNET_free (dk);
    942     return GNUNET_SYSERR;
    943   }
    944   GNUNET_CONTAINER_DLL_insert_after (denom->keys_head,
    945                                      denom->keys_tail,
    946                                      position,
    947                                      dk);
    948   return GNUNET_OK;
    949 }
    950 
    951 
    952 /**
    953  * The withdraw period of a key @a dk has expired. Purge it.
    954  *
    955  * @param[in] dk expired denomination key to purge
    956  */
    957 static void
    958 purge_key (struct DenominationKey *dk)
    959 {
    960   if (dk->purge)
    961     return;
    962   if (0 != unlink (dk->filename))
    963     GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
    964                               "unlink",
    965                               dk->filename);
    966   GNUNET_free (dk->filename);
    967   dk->purge = true;
    968   dk->key_gen = key_gen;
    969 }
    970 
    971 
    972 /**
    973  * A @a client informs us that a key has been revoked.
    974  * Check if the key is still in use, and if so replace (!)
    975  * it with a fresh key.
    976  *
    977  * @param client the client making the request
    978  * @param rr the revocation request
    979  */
    980 static enum GNUNET_GenericReturnValue
    981 handle_revoke_request (struct TES_Client *client,
    982                        const struct TALER_CRYPTO_RevokeRequest *rr)
    983 {
    984   struct DenominationKey *dk;
    985   struct DenominationKey *ndk;
    986   struct Denomination *denom;
    987 
    988   (void) client;
    989   GNUNET_assert (0 == pthread_mutex_lock (&keys_lock));
    990   dk = GNUNET_CONTAINER_multihashmap_get (keys,
    991                                           &rr->h_rsa.hash);
    992   if (NULL == dk)
    993   {
    994     GNUNET_assert (0 == pthread_mutex_unlock (&keys_lock));
    995     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
    996                 "Revocation request ignored, denomination key %s unknown\n",
    997                 GNUNET_h2s (&rr->h_rsa.hash));
    998     return GNUNET_OK;
    999   }
   1000   if (dk->purge)
   1001   {
   1002     GNUNET_assert (0 == pthread_mutex_unlock (&keys_lock));
   1003     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
   1004                 "Revocation request ignored, denomination key %s already revoked\n",
   1005                 GNUNET_h2s (&rr->h_rsa.hash));
   1006     return GNUNET_OK;
   1007   }
   1008 
   1009   key_gen++;
   1010   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   1011               "Revoking key %s, bumping generation to %llu\n",
   1012               GNUNET_h2s (&rr->h_rsa.hash),
   1013               (unsigned long long) key_gen);
   1014   purge_key (dk);
   1015 
   1016   /* Setup replacement key */
   1017   denom = dk->denom;
   1018   ndk = GNUNET_new (struct DenominationKey);
   1019   ndk->denom = denom;
   1020   ndk->anchor_start = dk->anchor_start;
   1021   ndk->anchor_end = dk->anchor_end;
   1022   if (GNUNET_OK !=
   1023       setup_key (ndk,
   1024                  dk))
   1025   {
   1026     GNUNET_assert (0 == pthread_mutex_unlock (&keys_lock));
   1027     GNUNET_break (0);
   1028     GNUNET_SCHEDULER_shutdown ();
   1029     globals->global_ret = EXIT_FAILURE;
   1030     return GNUNET_SYSERR;
   1031   }
   1032   GNUNET_assert (0 == pthread_mutex_unlock (&keys_lock));
   1033   TES_wake_clients ();
   1034   return GNUNET_OK;
   1035 }
   1036 
   1037 
   1038 /**
   1039  * Handle @a hdr message received from @a client.
   1040  *
   1041  * @param client the client that received the message
   1042  * @param hdr message that was received
   1043  * @return #GNUNET_OK on success
   1044  */
   1045 static enum GNUNET_GenericReturnValue
   1046 rsa_work_dispatch (struct TES_Client *client,
   1047                    const struct GNUNET_MessageHeader *hdr)
   1048 {
   1049   uint16_t msize = ntohs (hdr->size);
   1050 
   1051   switch (ntohs (hdr->type))
   1052   {
   1053   case TALER_HELPER_RSA_MT_REQ_SIGN:
   1054     if (msize <= sizeof (struct TALER_CRYPTO_SignRequest))
   1055     {
   1056       GNUNET_break_op (0);
   1057       return GNUNET_SYSERR;
   1058     }
   1059     return handle_sign_request (
   1060       client,
   1061       (const struct TALER_CRYPTO_SignRequest *) hdr);
   1062   case TALER_HELPER_RSA_MT_REQ_REVOKE:
   1063     if (msize != sizeof (struct TALER_CRYPTO_RevokeRequest))
   1064     {
   1065       GNUNET_break_op (0);
   1066       return GNUNET_SYSERR;
   1067     }
   1068     return handle_revoke_request (
   1069       client,
   1070       (const struct TALER_CRYPTO_RevokeRequest *) hdr);
   1071   case TALER_HELPER_RSA_MT_REQ_BATCH_SIGN:
   1072     if (msize <= sizeof (struct TALER_CRYPTO_BatchSignRequest))
   1073     {
   1074       GNUNET_break_op (0);
   1075       return GNUNET_SYSERR;
   1076     }
   1077     return handle_batch_sign_request (
   1078       client,
   1079       (const struct TALER_CRYPTO_BatchSignRequest *) hdr);
   1080   default:
   1081     GNUNET_break_op (0);
   1082     return GNUNET_SYSERR;
   1083   }
   1084 }
   1085 
   1086 
   1087 /**
   1088  * Send our initial key set to @a client together with the
   1089  * "sync" terminator.
   1090  *
   1091  * @param client the client to inform
   1092  * @return #GNUNET_OK on success
   1093  */
   1094 static enum GNUNET_GenericReturnValue
   1095 rsa_client_init (struct TES_Client *client)
   1096 {
   1097   size_t obs = 0;
   1098   char *buf;
   1099 
   1100   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   1101               "Initializing new client %p\n",
   1102               client);
   1103   GNUNET_assert (0 == pthread_mutex_lock (&keys_lock));
   1104   for (struct Denomination *denom = denom_head;
   1105        NULL != denom;
   1106        denom = denom->next)
   1107   {
   1108     for (struct DenominationKey *dk = denom->keys_head;
   1109          NULL != dk;
   1110          dk = dk->next)
   1111     {
   1112       GNUNET_assert (obs + ntohs (dk->an->header.size)
   1113                      > obs);
   1114       obs += ntohs (dk->an->header.size);
   1115     }
   1116   }
   1117   buf = GNUNET_malloc (obs);
   1118   obs = 0;
   1119   for (struct Denomination *denom = denom_head;
   1120        NULL != denom;
   1121        denom = denom->next)
   1122   {
   1123     for (struct DenominationKey *dk = denom->keys_head;
   1124          NULL != dk;
   1125          dk = dk->next)
   1126     {
   1127       GNUNET_memcpy (&buf[obs],
   1128                      dk->an,
   1129                      ntohs (dk->an->header.size));
   1130       GNUNET_assert (obs + ntohs (dk->an->header.size)
   1131                      > obs);
   1132       obs += ntohs (dk->an->header.size);
   1133     }
   1134   }
   1135   client->key_gen = key_gen;
   1136   GNUNET_assert (0 == pthread_mutex_unlock (&keys_lock));
   1137   if (GNUNET_OK !=
   1138       TES_transmit_raw (client->csock,
   1139                         obs,
   1140                         buf))
   1141   {
   1142     GNUNET_free (buf);
   1143     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   1144                 "Client %p must have disconnected\n",
   1145                 client);
   1146     return GNUNET_SYSERR;
   1147   }
   1148   GNUNET_free (buf);
   1149   {
   1150     struct GNUNET_MessageHeader synced = {
   1151       .type = htons (TALER_HELPER_RSA_SYNCED),
   1152       .size = htons (sizeof (synced))
   1153     };
   1154 
   1155     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   1156                 "Sending RSA SYNCED message to %p\n",
   1157                 client);
   1158     if (GNUNET_OK !=
   1159         TES_transmit (client->csock,
   1160                       &synced))
   1161     {
   1162       GNUNET_break (0);
   1163       return GNUNET_SYSERR;
   1164     }
   1165   }
   1166   return GNUNET_OK;
   1167 }
   1168 
   1169 
   1170 /**
   1171  * Notify @a client about all changes to the keys since
   1172  * the last generation known to the @a client.
   1173  *
   1174  * @param client the client to notify
   1175  * @return #GNUNET_OK on success
   1176  */
   1177 static enum GNUNET_GenericReturnValue
   1178 rsa_update_client_keys (struct TES_Client *client)
   1179 {
   1180   size_t obs = 0;
   1181   char *buf;
   1182   enum GNUNET_GenericReturnValue ret;
   1183 
   1184   GNUNET_assert (0 == pthread_mutex_lock (&keys_lock));
   1185   for (struct Denomination *denom = denom_head;
   1186        NULL != denom;
   1187        denom = denom->next)
   1188   {
   1189     for (struct DenominationKey *key = denom->keys_head;
   1190          NULL != key;
   1191          key = key->next)
   1192     {
   1193       if (key->key_gen <= client->key_gen)
   1194         continue;
   1195       if (key->purge)
   1196         obs += sizeof (struct TALER_CRYPTO_RsaKeyPurgeNotification);
   1197       else
   1198         obs += ntohs (key->an->header.size);
   1199     }
   1200   }
   1201   if (0 == obs)
   1202   {
   1203     /* nothing to do */
   1204     client->key_gen = key_gen;
   1205     GNUNET_assert (0 == pthread_mutex_unlock (&keys_lock));
   1206     return GNUNET_OK;
   1207   }
   1208   buf = GNUNET_malloc (obs);
   1209   obs = 0;
   1210   for (struct Denomination *denom = denom_head;
   1211        NULL != denom;
   1212        denom = denom->next)
   1213   {
   1214     for (struct DenominationKey *key = denom->keys_head;
   1215          NULL != key;
   1216          key = key->next)
   1217     {
   1218       if (key->key_gen <= client->key_gen)
   1219         continue;
   1220       if (key->purge)
   1221       {
   1222         struct TALER_CRYPTO_RsaKeyPurgeNotification pn = {
   1223           .header.type = htons (TALER_HELPER_RSA_MT_PURGE),
   1224           .header.size = htons (sizeof (pn)),
   1225           .h_rsa = key->h_rsa
   1226         };
   1227 
   1228         GNUNET_memcpy (&buf[obs],
   1229                        &pn,
   1230                        sizeof (pn));
   1231         GNUNET_assert (obs + sizeof (pn)
   1232                        > obs);
   1233         obs += sizeof (pn);
   1234       }
   1235       else
   1236       {
   1237         GNUNET_memcpy (&buf[obs],
   1238                        key->an,
   1239                        ntohs (key->an->header.size));
   1240         GNUNET_assert (obs + ntohs (key->an->header.size)
   1241                        > obs);
   1242         obs += ntohs (key->an->header.size);
   1243       }
   1244     }
   1245   }
   1246   client->key_gen = key_gen;
   1247   GNUNET_assert (0 == pthread_mutex_unlock (&keys_lock));
   1248   ret = TES_transmit_raw (client->csock,
   1249                           obs,
   1250                           buf);
   1251   GNUNET_free (buf);
   1252   return ret;
   1253 }
   1254 
   1255 
   1256 /**
   1257  * Create a new denomination key (we do not have enough).
   1258  *
   1259  * @param[in,out] denom denomination key to create
   1260  * @param anchor_start when to start key signing validity
   1261  * @param anchor_end when to end key signing validity
   1262  * @return #GNUNET_OK on success
   1263  */
   1264 static enum GNUNET_GenericReturnValue
   1265 create_key (struct Denomination *denom,
   1266             struct GNUNET_TIME_Timestamp anchor_start,
   1267             struct GNUNET_TIME_Timestamp anchor_end)
   1268 {
   1269   struct DenominationKey *dk;
   1270 
   1271   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
   1272               "Creating new key for `%s' with start date %s\n",
   1273               denom->section,
   1274               GNUNET_TIME_timestamp2s (anchor_start));
   1275   dk = GNUNET_new (struct DenominationKey);
   1276   dk->denom = denom;
   1277   dk->anchor_start = anchor_start;
   1278   dk->anchor_end = anchor_end;
   1279   if (GNUNET_OK !=
   1280       setup_key (dk,
   1281                  denom->keys_tail))
   1282   {
   1283     GNUNET_break (0);
   1284     GNUNET_free (dk);
   1285     GNUNET_SCHEDULER_shutdown ();
   1286     globals->global_ret = EXIT_FAILURE;
   1287     return GNUNET_SYSERR;
   1288   }
   1289   return GNUNET_OK;
   1290 }
   1291 
   1292 
   1293 /**
   1294  * Obtain the maximum withdraw duration of all denominations.
   1295  *
   1296  * Must only be called while the #keys_lock is held.
   1297  *
   1298  * @return maximum withdraw duration, zero if there are no denominations
   1299  */
   1300 static struct GNUNET_TIME_Relative
   1301 get_maximum_duration (void)
   1302 {
   1303   struct GNUNET_TIME_Relative ret
   1304     = GNUNET_TIME_UNIT_ZERO;
   1305 
   1306   for (struct Denomination *denom = denom_head;
   1307        NULL != denom;
   1308        denom = denom->next)
   1309   {
   1310     ret = GNUNET_TIME_relative_max (ret,
   1311                                     denom->duration_withdraw);
   1312   }
   1313   return ret;
   1314 }
   1315 
   1316 
   1317 /**
   1318  * At what time do we need to next create keys if we just did?
   1319  *
   1320  * @return time when to next create keys if we just finished key generation
   1321  */
   1322 static struct GNUNET_TIME_Absolute
   1323 action_time (void)
   1324 {
   1325   struct GNUNET_TIME_Relative md = get_maximum_duration ();
   1326   struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
   1327   uint64_t mod;
   1328 
   1329   if (GNUNET_TIME_relative_is_zero (md))
   1330     return GNUNET_TIME_UNIT_FOREVER_ABS;
   1331   mod = now.abs_value_us % md.rel_value_us;
   1332   now.abs_value_us -= mod;
   1333   return GNUNET_TIME_absolute_add (now,
   1334                                    md);
   1335 }
   1336 
   1337 
   1338 /**
   1339  * Remove all denomination keys of @a denom that have expired.
   1340  *
   1341  * @param[in,out] denom denomination family to remove keys for
   1342  */
   1343 static void
   1344 remove_expired_denomination_keys (struct Denomination *denom)
   1345 {
   1346   while ( (NULL != denom->keys_head) &&
   1347           GNUNET_TIME_absolute_is_past (
   1348             denom->keys_head->anchor_end.abs_time))
   1349   {
   1350     struct DenominationKey *key = denom->keys_head;
   1351     struct DenominationKey *nxt = key->next;
   1352 
   1353     if (0 != key->rc)
   1354       break; /* later */
   1355     GNUNET_CONTAINER_DLL_remove (denom->keys_head,
   1356                                  denom->keys_tail,
   1357                                  key);
   1358     GNUNET_assert (GNUNET_OK ==
   1359                    GNUNET_CONTAINER_multihashmap_remove (
   1360                      keys,
   1361                      &key->h_rsa.hash,
   1362                      key));
   1363     if ( (! key->purge) &&
   1364          (0 != unlink (key->filename)) )
   1365       GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
   1366                                 "unlink",
   1367                                 key->filename);
   1368     GNUNET_free (key->filename);
   1369     GNUNET_CRYPTO_rsa_private_key_free (key->denom_priv);
   1370     GNUNET_CRYPTO_rsa_public_key_free (key->denom_pub);
   1371     GNUNET_free (key->an);
   1372     GNUNET_free (key);
   1373     key = nxt;
   1374   }
   1375 }
   1376 
   1377 
   1378 /**
   1379  * Obtain the end anchor to use at this point. Uses the
   1380  * #lookahead_sign and then rounds it up by the maximum
   1381  * duration of any denomination to arrive at a globally
   1382  * valid end-date.
   1383  *
   1384  * Must only be called while the #keys_lock is held.
   1385  *
   1386  * @return end anchor
   1387  */
   1388 static struct GNUNET_TIME_Timestamp
   1389 get_anchor_end (void)
   1390 {
   1391   struct GNUNET_TIME_Relative md = get_maximum_duration ();
   1392   struct GNUNET_TIME_Absolute end
   1393     = GNUNET_TIME_relative_to_absolute (lookahead_sign);
   1394   uint64_t mod;
   1395 
   1396   if (GNUNET_TIME_relative_is_zero (md))
   1397     return GNUNET_TIME_UNIT_ZERO_TS;
   1398   /* Round up 'end' to a multiple of 'md' */
   1399   mod = end.abs_value_us % md.rel_value_us;
   1400   end.abs_value_us -= mod;
   1401   return GNUNET_TIME_absolute_to_timestamp (
   1402     GNUNET_TIME_absolute_add (end,
   1403                               md));
   1404 }
   1405 
   1406 
   1407 /**
   1408  * Create all denomination keys that are required for our
   1409  * desired lookahead and that we do not yet have.
   1410  *
   1411  * @param[in,out] opt our options
   1412  * @param[in,out] wake set to true if we should wake the clients
   1413  */
   1414 static void
   1415 create_missing_keys (struct TALER_SECMOD_Options *opt,
   1416                      bool *wake)
   1417 {
   1418   struct GNUNET_TIME_Timestamp start;
   1419   struct GNUNET_TIME_Timestamp end;
   1420 
   1421   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
   1422               "Updating denominations ...\n");
   1423   start = opt->global_now;
   1424   GNUNET_assert (0 == pthread_mutex_lock (&keys_lock));
   1425   end = get_anchor_end ();
   1426   for (struct Denomination *denom = denom_head;
   1427        NULL != denom;
   1428        denom = denom->next)
   1429   {
   1430     struct GNUNET_TIME_Timestamp anchor_start;
   1431     struct GNUNET_TIME_Timestamp anchor_end;
   1432     struct GNUNET_TIME_Timestamp next_end;
   1433     bool finished = false;
   1434 
   1435     remove_expired_denomination_keys (denom);
   1436     if (NULL != denom->keys_tail)
   1437     {
   1438       anchor_start = denom->keys_tail->anchor_end;
   1439       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   1440                   "Expanding keys of denomination `%s', last key %s valid for another %s\n",
   1441                   denom->section,
   1442                   GNUNET_h2s (&denom->keys_tail->h_rsa.hash),
   1443                   GNUNET_TIME_relative2s (
   1444                     GNUNET_TIME_absolute_get_remaining (
   1445                       anchor_start.abs_time),
   1446                     true));
   1447     }
   1448     else
   1449     {
   1450       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   1451                   "Starting keys of denomination `%s'\n",
   1452                   denom->section);
   1453       anchor_start = start;
   1454     }
   1455     finished = GNUNET_TIME_timestamp_cmp (anchor_start,
   1456                                           >=,
   1457                                           end);
   1458     while (! finished)
   1459     {
   1460       anchor_end = GNUNET_TIME_absolute_to_timestamp (
   1461         GNUNET_TIME_absolute_add (anchor_start.abs_time,
   1462                                   denom->duration_withdraw));
   1463       next_end = GNUNET_TIME_absolute_to_timestamp (
   1464         GNUNET_TIME_absolute_add (anchor_end.abs_time,
   1465                                   denom->duration_withdraw));
   1466       if (GNUNET_TIME_timestamp_cmp (next_end,
   1467                                      >,
   1468                                      end))
   1469       {
   1470         anchor_end = end; /* extend period to align end periods */
   1471         finished = true;
   1472       }
   1473       /* adjust start time down to ensure overlap */
   1474       anchor_start = GNUNET_TIME_absolute_to_timestamp (
   1475         GNUNET_TIME_absolute_subtract (anchor_start.abs_time,
   1476                                        overlap_duration));
   1477       if (! *wake)
   1478       {
   1479         key_gen++;
   1480         *wake = true;
   1481       }
   1482       if (GNUNET_OK !=
   1483           create_key (denom,
   1484                       anchor_start,
   1485                       anchor_end))
   1486       {
   1487         GNUNET_break (0);
   1488         GNUNET_assert (0 == pthread_mutex_unlock (&keys_lock));
   1489         globals->global_ret = EXIT_FAILURE;
   1490         GNUNET_SCHEDULER_shutdown ();
   1491         return;
   1492       }
   1493       anchor_start = anchor_end;
   1494     }
   1495     remove_expired_denomination_keys (denom);
   1496   }
   1497   GNUNET_assert (0 == pthread_mutex_unlock (&keys_lock));
   1498   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
   1499               "Updating denominations finished ...\n");
   1500 }
   1501 
   1502 
   1503 /**
   1504  * Task run periodically to expire keys and/or generate fresh ones.
   1505  *
   1506  * @param cls the `struct TALER_SECMOD_Options *`
   1507  */
   1508 static void
   1509 update_denominations (void *cls)
   1510 {
   1511   struct TALER_SECMOD_Options *opt = cls;
   1512   struct GNUNET_TIME_Absolute at;
   1513   bool wake = false;
   1514 
   1515   (void) cls;
   1516   keygen_task = NULL;
   1517   /* update current time, global override no longer applies */
   1518   opt->global_now = GNUNET_TIME_timestamp_get ();
   1519   create_missing_keys (opt,
   1520                        &wake);
   1521   if (wake)
   1522     TES_wake_clients ();
   1523   at = action_time ();
   1524   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
   1525               "Next key generation due at %s\n",
   1526               GNUNET_TIME_absolute2s (at));
   1527   keygen_task = GNUNET_SCHEDULER_add_at (at,
   1528                                          &update_denominations,
   1529                                          opt);
   1530 }
   1531 
   1532 
   1533 /**
   1534  * Parse private key of denomination @a denom in @a buf.
   1535  *
   1536  * @param[out] denom denomination of the key
   1537  * @param filename name of the file we are parsing, for logging
   1538  * @param buf key material
   1539  * @param buf_size number of bytes in @a buf
   1540  */
   1541 static void
   1542 parse_key (struct Denomination *denom,
   1543            const char *filename,
   1544            const void *buf,
   1545            size_t buf_size)
   1546 {
   1547   struct GNUNET_CRYPTO_RsaPrivateKey *priv;
   1548   const char *anchor_s;
   1549   char dummy;
   1550   unsigned long long anchor_start_ll;
   1551   unsigned long long anchor_end_ll;
   1552   struct GNUNET_TIME_Timestamp anchor_start;
   1553   struct GNUNET_TIME_Timestamp anchor_end;
   1554   char *nf = NULL;
   1555 
   1556   anchor_s = strrchr (filename,
   1557                       '/');
   1558   if (NULL == anchor_s)
   1559   {
   1560     /* File in a directory without '/' in the name, this makes no sense. */
   1561     GNUNET_break (0);
   1562     return;
   1563   }
   1564   anchor_s++;
   1565   if (2 != sscanf (anchor_s,
   1566                    "%llu-%llu%c",
   1567                    &anchor_start_ll,
   1568                    &anchor_end_ll,
   1569                    &dummy))
   1570   {
   1571     /* try legacy mode */
   1572     if (1 != sscanf (anchor_s,
   1573                      "%llu%c",
   1574                      &anchor_start_ll,
   1575                      &dummy))
   1576     {
   1577       /* Filenames in KEYDIR must ONLY be the anchor time in seconds! */
   1578       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
   1579                   "Filename `%s' invalid for key file, skipping\n",
   1580                   anchor_s);
   1581       return;
   1582     }
   1583     anchor_start.abs_time.abs_value_us
   1584       = anchor_start_ll * GNUNET_TIME_UNIT_SECONDS.rel_value_us;
   1585     if (anchor_start_ll != anchor_start.abs_time.abs_value_us
   1586         / GNUNET_TIME_UNIT_SECONDS.rel_value_us)
   1587     {
   1588       /* Integer overflow. Bad, invalid filename. */
   1589       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
   1590                   "Integer overflow. Filename `%s' invalid for key file, skipping\n",
   1591                   anchor_s);
   1592       return;
   1593     }
   1594     anchor_end
   1595       = GNUNET_TIME_absolute_to_timestamp (
   1596           GNUNET_TIME_absolute_add (anchor_start.abs_time,
   1597                                     denom->duration_withdraw));
   1598     GNUNET_asprintf (
   1599       &nf,
   1600       "%s/%s/%llu-%llu",
   1601       keydir,
   1602       denom->section,
   1603       anchor_start_ll,
   1604       (unsigned long long) (anchor_end.abs_time.abs_value_us
   1605                             / GNUNET_TIME_UNIT_SECONDS.rel_value_us));
   1606     /* Try to fix the legacy filename */
   1607     if (0 !=
   1608         rename (filename,
   1609                 nf))
   1610     {
   1611       GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
   1612                                 "rename",
   1613                                 filename);
   1614       GNUNET_free (nf);
   1615     }
   1616   }
   1617   else
   1618   {
   1619     anchor_start.abs_time.abs_value_us
   1620       = anchor_start_ll * GNUNET_TIME_UNIT_SECONDS.rel_value_us;
   1621     anchor_end.abs_time.abs_value_us
   1622       = anchor_end_ll * GNUNET_TIME_UNIT_SECONDS.rel_value_us;
   1623     if ( (anchor_start_ll != anchor_start.abs_time.abs_value_us
   1624           / GNUNET_TIME_UNIT_SECONDS.rel_value_us) ||
   1625          (anchor_end_ll != anchor_end.abs_time.abs_value_us
   1626           / GNUNET_TIME_UNIT_SECONDS.rel_value_us) )
   1627     {
   1628       /* Integer overflow. Bad, invalid filename. */
   1629       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
   1630                   "Integer overflow. Filename `%s' invalid for key file, skipping\n",
   1631                   anchor_s);
   1632       return;
   1633     }
   1634   }
   1635   priv = GNUNET_CRYPTO_rsa_private_key_decode (buf,
   1636                                                buf_size);
   1637   if (NULL == priv)
   1638   {
   1639     /* Parser failure. */
   1640     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
   1641                 "File `%s' is malformed, skipping\n",
   1642                 (NULL == nf) ? filename : nf);
   1643     GNUNET_free (nf);
   1644     return;
   1645   }
   1646 
   1647   {
   1648     struct GNUNET_CRYPTO_RsaPublicKey *pub;
   1649     struct DenominationKey *dk;
   1650     struct DenominationKey *before;
   1651 
   1652     pub = GNUNET_CRYPTO_rsa_private_key_get_public (priv);
   1653     if (NULL == pub)
   1654     {
   1655       GNUNET_break (0);
   1656       GNUNET_CRYPTO_rsa_private_key_free (priv);
   1657       GNUNET_free (nf);
   1658       return;
   1659     }
   1660     dk = GNUNET_new (struct DenominationKey);
   1661     dk->denom_priv = priv;
   1662     dk->denom = denom;
   1663     dk->anchor_start = anchor_start;
   1664     dk->anchor_end = anchor_end;
   1665     dk->filename = (NULL == nf) ? GNUNET_strdup (filename) : nf;
   1666     GNUNET_CRYPTO_rsa_public_key_hash (pub,
   1667                                        &dk->h_rsa.hash);
   1668     dk->denom_pub = pub;
   1669     generate_response (dk);
   1670     if (GNUNET_OK !=
   1671         GNUNET_CONTAINER_multihashmap_put (
   1672           keys,
   1673           &dk->h_rsa.hash,
   1674           dk,
   1675           GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
   1676     {
   1677       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
   1678                   "Duplicate private key %s detected in file `%s'. Skipping.\n",
   1679                   GNUNET_h2s (&dk->h_rsa.hash),
   1680                   filename);
   1681       GNUNET_CRYPTO_rsa_private_key_free (priv);
   1682       GNUNET_CRYPTO_rsa_public_key_free (pub);
   1683       GNUNET_free (dk->an);
   1684       GNUNET_free (dk);
   1685       return;
   1686     }
   1687     before = NULL;
   1688     for (struct DenominationKey *pos = denom->keys_head;
   1689          NULL != pos;
   1690          pos = pos->next)
   1691     {
   1692       if (GNUNET_TIME_timestamp_cmp (pos->anchor_start,
   1693                                      >,
   1694                                      anchor_start))
   1695         break;
   1696       before = pos;
   1697     }
   1698     GNUNET_CONTAINER_DLL_insert_after (denom->keys_head,
   1699                                        denom->keys_tail,
   1700                                        before,
   1701                                        dk);
   1702     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   1703                 "Imported key %s from `%s'\n",
   1704                 GNUNET_h2s (&dk->h_rsa.hash),
   1705                 filename);
   1706   }
   1707 }
   1708 
   1709 
   1710 /**
   1711  * Import a private key from @a filename for the denomination
   1712  * given in @a cls.
   1713  *
   1714  * @param[in,out] cls a `struct Denomiantion`
   1715  * @param filename name of a file in the directory
   1716  * @return #GNUNET_OK (always, continue to iterate)
   1717  */
   1718 static enum GNUNET_GenericReturnValue
   1719 import_key (void *cls,
   1720             const char *filename)
   1721 {
   1722   struct Denomination *denom = cls;
   1723   struct GNUNET_DISK_FileHandle *fh;
   1724   struct GNUNET_DISK_MapHandle *map;
   1725   void *ptr;
   1726   int fd;
   1727   struct stat sbuf;
   1728 
   1729   {
   1730     struct stat lsbuf;
   1731 
   1732     if (0 != lstat (filename,
   1733                     &lsbuf))
   1734     {
   1735       GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
   1736                                 "lstat",
   1737                                 filename);
   1738       return GNUNET_OK;
   1739     }
   1740     if (! S_ISREG (lsbuf.st_mode))
   1741     {
   1742       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
   1743                   "File `%s' is not a regular file, which is not allowed for private keys!\n",
   1744                   filename);
   1745       return GNUNET_OK;
   1746     }
   1747   }
   1748 
   1749   fd = open (filename,
   1750              O_RDONLY | O_CLOEXEC);
   1751   if (-1 == fd)
   1752   {
   1753     GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
   1754                               "open",
   1755                               filename);
   1756     return GNUNET_OK;
   1757   }
   1758   if (0 != fstat (fd,
   1759                   &sbuf))
   1760   {
   1761     GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
   1762                               "stat",
   1763                               filename);
   1764     GNUNET_break (0 == close (fd));
   1765     return GNUNET_OK;
   1766   }
   1767   if (! S_ISREG (sbuf.st_mode))
   1768   {
   1769     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
   1770                 "File `%s' is not a regular file, which is not allowed for private keys!\n",
   1771                 filename);
   1772     GNUNET_break (0 == close (fd));
   1773     return GNUNET_OK;
   1774   }
   1775   if (0 != (sbuf.st_mode & (S_IWUSR | S_IRWXG | S_IRWXO)))
   1776   {
   1777     /* permission are NOT tight, try to patch them up! */
   1778     if (0 !=
   1779         fchmod (fd,
   1780                 S_IRUSR))
   1781     {
   1782       GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
   1783                                 "fchmod",
   1784                                 filename);
   1785       /* refuse to use key if file has wrong permissions */
   1786       GNUNET_break (0 == close (fd));
   1787       return GNUNET_OK;
   1788     }
   1789   }
   1790   fh = GNUNET_DISK_get_handle_from_int_fd (fd);
   1791   if (NULL == fh)
   1792   {
   1793     GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
   1794                               "open",
   1795                               filename);
   1796     GNUNET_break (0 == close (fd));
   1797     return GNUNET_OK;
   1798   }
   1799   if (sbuf.st_size > 16 * 1024)
   1800   {
   1801     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
   1802                 "File `%s' too big to be a private key\n",
   1803                 filename);
   1804     GNUNET_DISK_file_close (fh);
   1805     return GNUNET_OK;
   1806   }
   1807   ptr = GNUNET_DISK_file_map (fh,
   1808                               &map,
   1809                               GNUNET_DISK_MAP_TYPE_READ,
   1810                               (size_t) sbuf.st_size);
   1811   if (NULL == ptr)
   1812   {
   1813     GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
   1814                               "mmap",
   1815                               filename);
   1816     GNUNET_DISK_file_close (fh);
   1817     return GNUNET_OK;
   1818   }
   1819   parse_key (denom,
   1820              filename,
   1821              ptr,
   1822              (size_t) sbuf.st_size);
   1823   GNUNET_DISK_file_unmap (map);
   1824   GNUNET_DISK_file_close (fh);
   1825   return GNUNET_OK;
   1826 }
   1827 
   1828 
   1829 /**
   1830  * Parse configuration for denomination type parameters.  Also determines
   1831  * our anchor by looking at the existing denominations of the same type.
   1832  *
   1833  * @param cfg configuration to use
   1834  * @param ct section in the configuration file giving the denomination type parameters
   1835  * @param[out] denom set to the denomination parameters from the configuration
   1836  * @return #GNUNET_OK on success, #GNUNET_SYSERR if the configuration is invalid
   1837  */
   1838 static enum GNUNET_GenericReturnValue
   1839 parse_denomination_cfg (const struct GNUNET_CONFIGURATION_Handle *cfg,
   1840                         const char *ct,
   1841                         struct Denomination *denom)
   1842 {
   1843   unsigned long long rsa_keysize;
   1844   char *secname;
   1845 
   1846   GNUNET_asprintf (&secname,
   1847                    "%s-secmod-rsa",
   1848                    globals->section);
   1849   if (GNUNET_OK !=
   1850       GNUNET_CONFIGURATION_get_value_time (cfg,
   1851                                            ct,
   1852                                            "DURATION_WITHDRAW",
   1853                                            &denom->duration_withdraw))
   1854   {
   1855     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
   1856                                ct,
   1857                                "DURATION_WITHDRAW");
   1858     GNUNET_free (secname);
   1859     return GNUNET_SYSERR;
   1860   }
   1861   if (GNUNET_TIME_relative_cmp (denom->duration_withdraw,
   1862                                 <,
   1863                                 GNUNET_TIME_UNIT_SECONDS))
   1864   {
   1865     GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
   1866                                ct,
   1867                                "DURATION_WITHDRAW",
   1868                                "less than one second is not supported");
   1869     GNUNET_free (secname);
   1870     return GNUNET_SYSERR;
   1871   }
   1872   if (GNUNET_TIME_relative_cmp (overlap_duration,
   1873                                 >=,
   1874                                 denom->duration_withdraw))
   1875   {
   1876     GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
   1877                                secname,
   1878                                "OVERLAP_DURATION",
   1879                                "Value given must be smaller than value for DURATION_WITHDRAW!");
   1880     GNUNET_free (secname);
   1881     return GNUNET_SYSERR;
   1882   }
   1883   if (GNUNET_OK !=
   1884       GNUNET_CONFIGURATION_get_value_number (cfg,
   1885                                              ct,
   1886                                              "RSA_KEYSIZE",
   1887                                              &rsa_keysize))
   1888   {
   1889     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
   1890                                ct,
   1891                                "RSA_KEYSIZE");
   1892     GNUNET_free (secname);
   1893     return GNUNET_SYSERR;
   1894   }
   1895   if ( (rsa_keysize > 4 * 2048) ||
   1896        (rsa_keysize < 1024) )
   1897   {
   1898     GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
   1899                                ct,
   1900                                "RSA_KEYSIZE",
   1901                                "Given RSA keysize outside of permitted range [1024,8192]\n");
   1902     GNUNET_free (secname);
   1903     return GNUNET_SYSERR;
   1904   }
   1905   GNUNET_free (secname);
   1906   denom->rsa_keysize = (unsigned int) rsa_keysize;
   1907   denom->section = GNUNET_strdup (ct);
   1908   return GNUNET_OK;
   1909 }
   1910 
   1911 
   1912 /**
   1913  * Closure for #load_denominations.
   1914  */
   1915 struct LoadContext
   1916 {
   1917 
   1918   /**
   1919    * Configuration to use.
   1920    */
   1921   const struct GNUNET_CONFIGURATION_Handle *cfg;
   1922 
   1923   /**
   1924    * Configuration section prefix to use for denomination settings.
   1925    * "coin_" for the exchange, "doco_" for Donau.
   1926    */
   1927   const char *cprefix;
   1928 
   1929   /**
   1930    * Status, to be set to #GNUNET_SYSERR on failure
   1931    */
   1932   enum GNUNET_GenericReturnValue ret;
   1933 };
   1934 
   1935 
   1936 /**
   1937  * Generate new denomination signing keys for the denomination type of the given @a
   1938  * denomination_alias.
   1939  *
   1940  * @param cls a `struct LoadContext`, with 'ret' to be set to #GNUNET_SYSERR on failure
   1941  * @param denomination_alias name of the denomination's section in the configuration
   1942  */
   1943 static void
   1944 load_denominations (void *cls,
   1945                     const char *denomination_alias)
   1946 {
   1947   struct LoadContext *ctx = cls;
   1948   struct Denomination *denom;
   1949   char *cipher;
   1950 
   1951   if (0 != strncasecmp (denomination_alias,
   1952                         ctx->cprefix,
   1953                         strlen (ctx->cprefix)))
   1954     return; /* not a denomination type definition */
   1955   if (GNUNET_OK !=
   1956       GNUNET_CONFIGURATION_get_value_string (ctx->cfg,
   1957                                              denomination_alias,
   1958                                              "CIPHER",
   1959                                              &cipher))
   1960   {
   1961     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
   1962                                denomination_alias,
   1963                                "CIPHER");
   1964     return;
   1965   }
   1966   if (0 != strcmp (cipher,
   1967                    "RSA"))
   1968   {
   1969     GNUNET_free (cipher);
   1970     return; /* Ignore denominations of other types than CS */
   1971   }
   1972   GNUNET_free (cipher);
   1973   denom = GNUNET_new (struct Denomination);
   1974   if (GNUNET_OK !=
   1975       parse_denomination_cfg (ctx->cfg,
   1976                               denomination_alias,
   1977                               denom))
   1978   {
   1979     ctx->ret = GNUNET_SYSERR;
   1980     GNUNET_free (denom);
   1981     return;
   1982   }
   1983   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   1984               "Loading keys for denomination %s\n",
   1985               denom->section);
   1986   {
   1987     char *dname;
   1988 
   1989     GNUNET_asprintf (&dname,
   1990                      "%s/%s",
   1991                      keydir,
   1992                      denom->section);
   1993     GNUNET_break (GNUNET_OK ==
   1994                   GNUNET_DISK_directory_create (dname));
   1995     GNUNET_DISK_directory_scan (dname,
   1996                                 &import_key,
   1997                                 denom);
   1998     GNUNET_free (dname);
   1999   }
   2000   GNUNET_CONTAINER_DLL_insert (denom_head,
   2001                                denom_tail,
   2002                                denom);
   2003 }
   2004 
   2005 
   2006 /**
   2007  * Load the various duration values from @a cfg
   2008  *
   2009  * @param cfg configuration to use
   2010  * @return #GNUNET_OK on success
   2011  */
   2012 static enum GNUNET_GenericReturnValue
   2013 load_durations (const struct GNUNET_CONFIGURATION_Handle *cfg)
   2014 {
   2015   char *secname;
   2016 
   2017   GNUNET_asprintf (&secname,
   2018                    "%s-secmod-rsa",
   2019                    globals->section);
   2020   if (GNUNET_OK !=
   2021       GNUNET_CONFIGURATION_get_value_time (cfg,
   2022                                            secname,
   2023                                            "OVERLAP_DURATION",
   2024                                            &overlap_duration))
   2025   {
   2026     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
   2027                                secname,
   2028                                "OVERLAP_DURATION");
   2029     GNUNET_free (secname);
   2030     return GNUNET_SYSERR;
   2031   }
   2032   if (GNUNET_OK !=
   2033       GNUNET_CONFIGURATION_get_value_time (cfg,
   2034                                            secname,
   2035                                            "LOOKAHEAD_SIGN",
   2036                                            &lookahead_sign))
   2037   {
   2038     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
   2039                                secname,
   2040                                "LOOKAHEAD_SIGN");
   2041     GNUNET_free (secname);
   2042     return GNUNET_SYSERR;
   2043   }
   2044   GNUNET_free (secname);
   2045   return GNUNET_OK;
   2046 }
   2047 
   2048 
   2049 /**
   2050  * Function run on shutdown. Stops the various jobs (nicely).
   2051  *
   2052  * @param cls NULL
   2053  */
   2054 static void
   2055 do_shutdown (void *cls)
   2056 {
   2057   (void) cls;
   2058   TES_listen_stop ();
   2059   if (NULL != keygen_task)
   2060   {
   2061     GNUNET_SCHEDULER_cancel (keygen_task);
   2062     keygen_task = NULL;
   2063   }
   2064   stop_workers ();
   2065   sem_done (&worker_sem);
   2066 }
   2067 
   2068 
   2069 void
   2070 TALER_SECMOD_rsa_run (void *cls,
   2071                       char *const *args,
   2072                       const char *cfgfile,
   2073                       const struct GNUNET_CONFIGURATION_Handle *cfg)
   2074 {
   2075   static struct TES_Callbacks cb = {
   2076     .dispatch = rsa_work_dispatch,
   2077     .updater = rsa_update_client_keys,
   2078     .init = rsa_client_init
   2079   };
   2080   struct TALER_SECMOD_Options *opt = cls;
   2081   char *secname;
   2082 
   2083   (void) args;
   2084   (void) cfgfile;
   2085   globals = opt;
   2086   if (GNUNET_TIME_timestamp_cmp (opt->global_now,
   2087                                  !=,
   2088                                  opt->global_now_tmp))
   2089   {
   2090     /* The user gave "--now", use it! */
   2091     opt->global_now = opt->global_now_tmp;
   2092   }
   2093   else
   2094   {
   2095     /* get current time again, we may be timetraveling! */
   2096     opt->global_now = GNUNET_TIME_timestamp_get ();
   2097   }
   2098   GNUNET_asprintf (&secname,
   2099                    "%s-secmod-rsa",
   2100                    opt->section);
   2101   if (GNUNET_OK !=
   2102       GNUNET_CONFIGURATION_get_value_filename (cfg,
   2103                                                secname,
   2104                                                "KEY_DIR",
   2105                                                &keydir))
   2106   {
   2107     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
   2108                                secname,
   2109                                "KEY_DIR");
   2110     GNUNET_free (secname);
   2111     opt->global_ret = EXIT_NOTCONFIGURED;
   2112     return;
   2113   }
   2114   if (GNUNET_OK !=
   2115       load_durations (cfg))
   2116   {
   2117     opt->global_ret = EXIT_NOTCONFIGURED;
   2118     GNUNET_free (secname);
   2119     return;
   2120   }
   2121   opt->global_ret = TES_listen_start (cfg,
   2122                                       secname,
   2123                                       &cb);
   2124   GNUNET_free (secname);
   2125   if (0 != opt->global_ret)
   2126     return;
   2127   sem_init (&worker_sem,
   2128             0);
   2129   GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
   2130                                  NULL);
   2131   if (0 == opt->max_workers)
   2132   {
   2133     long lret;
   2134 
   2135     lret = sysconf (_SC_NPROCESSORS_CONF);
   2136     if (lret <= 0)
   2137       lret = 1;
   2138     opt->max_workers = (unsigned int) lret;
   2139   }
   2140 
   2141   for (unsigned int i = 0; i<opt->max_workers; i++)
   2142     if (GNUNET_OK !=
   2143         start_worker ())
   2144     {
   2145       GNUNET_SCHEDULER_shutdown ();
   2146       return;
   2147     }
   2148   /* Load denominations */
   2149   keys = GNUNET_CONTAINER_multihashmap_create (65536,
   2150                                                true);
   2151   {
   2152     struct LoadContext lc = {
   2153       .cfg = cfg,
   2154       .ret = GNUNET_OK,
   2155       .cprefix = opt->cprefix
   2156     };
   2157     bool wake = true;
   2158 
   2159     GNUNET_assert (0 == pthread_mutex_lock (&keys_lock));
   2160     GNUNET_CONFIGURATION_iterate_sections (cfg,
   2161                                            &load_denominations,
   2162                                            &lc);
   2163     GNUNET_assert (0 == pthread_mutex_unlock (&keys_lock));
   2164     if (GNUNET_OK != lc.ret)
   2165     {
   2166       opt->global_ret = EXIT_FAILURE;
   2167       GNUNET_SCHEDULER_shutdown ();
   2168       return;
   2169     }
   2170     create_missing_keys (opt,
   2171                          &wake);
   2172   }
   2173   if (NULL == denom_head)
   2174   {
   2175     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
   2176                 "No RSA denominations configured. Make sure section names start with `%s' if you are using RSA!\n",
   2177                 opt->cprefix);
   2178     TES_wake_clients ();
   2179     return;
   2180   }
   2181   /* start job to keep keys up-to-date; MUST be run before the #listen_task,
   2182      hence with priority. */
   2183   keygen_task = GNUNET_SCHEDULER_add_with_priority (
   2184     GNUNET_SCHEDULER_PRIORITY_URGENT,
   2185     &update_denominations,
   2186     opt);
   2187 }