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