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