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