taler-exchange-httpd_secmod-helpers.c (28527B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2020-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 Affero 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 Affero General Public License for more details. 12 13 You should have received a copy of the GNU Affero General Public License along with 14 TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> 15 */ 16 /** 17 * @file taler-exchange-httpd_secmod-helpers.c 18 * @brief management of state with secmod helpers 19 * @author Christian Grothoff 20 * @author Özgür Kesim 21 */ 22 #include "taler/taler_json_lib.h" 23 #include "taler/taler_mhd_lib.h" 24 #include "taler-exchange-httpd.h" 25 #include "taler-exchange-httpd_get-keys.h" 26 #include "taler-exchange-httpd_secmod-helpers.h" 27 #include "taler-exchange-httpd_configuration.h" 28 29 30 /** 31 * For how long should a signing key be legally retained? 32 * Configuration value. 33 */ 34 static struct GNUNET_TIME_Relative signkey_legal_duration; 35 36 /** 37 * Handle for the esign/EdDSA helper. 38 */ 39 static struct TALER_CRYPTO_ExchangeSignHelper *esh; 40 41 /** 42 * Handle for the denom/RSA helper. 43 */ 44 static struct TALER_CRYPTO_RsaDenominationHelper *rsadh; 45 46 /** 47 * Handle for the denom/CS helper. 48 */ 49 static struct TALER_CRYPTO_CsDenominationHelper *csdh; 50 51 /** 52 * Map from H(denom_pub) to `struct HelperDenomination` entries. 53 */ 54 static struct GNUNET_CONTAINER_MultiHashMap *denom_keys; 55 56 /** 57 * Map from H(rsa_pub) to `struct HelperDenomination` entries. 58 */ 59 static struct GNUNET_CONTAINER_MultiHashMap *rsa_keys; 60 61 /** 62 * Map from H(cs_pub) to `struct HelperDenomination` entries. 63 */ 64 static struct GNUNET_CONTAINER_MultiHashMap *cs_keys; 65 66 /** 67 * Map from `struct TALER_ExchangePublicKey` to `struct HelperSignkey` 68 * entries. Based on the fact that a `struct GNUNET_PeerIdentity` is also 69 * an EdDSA public key. 70 */ 71 static struct GNUNET_CONTAINER_MultiPeerMap *esign_keys; 72 73 /** 74 * RSA security module public key, all zero if not known. 75 */ 76 static struct TALER_SecurityModulePublicKeyP denom_rsa_sm_pub; 77 78 /** 79 * CS security module public key, all zero if not known. 80 */ 81 static struct TALER_SecurityModulePublicKeyP denom_cs_sm_pub; 82 83 /** 84 * EdDSA security module public key, all zero if not known. 85 */ 86 static struct TALER_SecurityModulePublicKeyP esign_sm_pub; 87 88 89 bool 90 TEH_SECMOD_have_denom_sm_pub () 91 { 92 return 93 (! GNUNET_is_zero (&denom_rsa_sm_pub)) || 94 (! GNUNET_is_zero (&denom_cs_sm_pub)); 95 } 96 97 98 bool 99 TEH_SECMOD_have_esign_sm_pub () 100 { 101 return ! GNUNET_is_zero (&esign_sm_pub); 102 } 103 104 105 json_t * 106 TEH_SECMOD_get_sm_pubs_as_json () 107 { 108 return GNUNET_JSON_PACK ( 109 GNUNET_JSON_pack_data_auto ("denom_secmod_public_key", 110 &denom_rsa_sm_pub), 111 GNUNET_JSON_pack_data_auto ("denom_secmod_cs_public_key", 112 &denom_cs_sm_pub), 113 GNUNET_JSON_pack_data_auto ("signkey_secmod_public_key", 114 &esign_sm_pub)); 115 } 116 117 118 /** 119 * Check that the given RSA security module's public key is the one 120 * we have pinned. If it does not match, we die hard. 121 * 122 * @param sm_pub RSA security module public key to check 123 */ 124 static void 125 check_denom_rsa_sm_pub (const struct TALER_SecurityModulePublicKeyP *sm_pub) 126 { 127 if (0 != 128 GNUNET_memcmp (sm_pub, 129 &denom_rsa_sm_pub)) 130 { 131 if (! GNUNET_is_zero (&denom_rsa_sm_pub)) 132 { 133 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 134 "Our RSA security module changed its key. This must not happen.\n"); 135 GNUNET_assert (0); 136 } 137 denom_rsa_sm_pub = *sm_pub; /* TOFU ;-) */ 138 } 139 } 140 141 142 /** 143 * Function called with information about available keys for signing. Usually 144 * only called once per key upon connect. Also called again in case a key is 145 * being revoked, in that case with an @a end_time of zero. 146 * 147 * @param cls NULL 148 * @param section_name name of the denomination type in the configuration; 149 * NULL if the key has been revoked or purged 150 * @param start_time when does the key become available for signing; 151 * zero if the key has been revoked or purged 152 * @param validity_duration how long does the key remain available for signing; 153 * zero if the key has been revoked or purged 154 * @param h_rsa hash of the @a denom_pub that is available (or was purged) 155 * @param bs_pub the public key itself, NULL if the key was revoked or purged 156 * @param sm_pub public key of the security module, NULL if the key was revoked or purged 157 * @param sm_sig signature from the security module 158 */ 159 static void 160 helper_rsa_cb ( 161 void *cls, 162 const char *section_name, 163 struct GNUNET_TIME_Timestamp start_time, 164 struct GNUNET_TIME_Relative validity_duration, 165 const struct TALER_RsaPubHashP *h_rsa, 166 struct GNUNET_CRYPTO_BlindSignPublicKey *bs_pub, 167 const struct TALER_SecurityModulePublicKeyP *sm_pub, 168 const struct TALER_SecurityModuleSignatureP *sm_sig) 169 { 170 struct HelperDenomination *hd; 171 172 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 173 "RSA helper announces key %s for denomination type %s with validity %s\n", 174 GNUNET_h2s (&h_rsa->hash), 175 section_name, 176 GNUNET_STRINGS_relative_time_to_string (validity_duration, 177 GNUNET_NO)); 178 TEH_keys_bump_generation (); 179 TEH_resume_keys_requests (false); 180 hd = GNUNET_CONTAINER_multihashmap_get (rsa_keys, 181 &h_rsa->hash); 182 if (NULL != hd) 183 { 184 /* should be just an update (revocation!), so update existing entry */ 185 hd->validity_duration = validity_duration; 186 return; 187 } 188 GNUNET_assert (NULL != sm_pub); 189 check_denom_rsa_sm_pub (sm_pub); 190 hd = GNUNET_new (struct HelperDenomination); 191 hd->start_time = start_time; 192 hd->validity_duration = validity_duration; 193 hd->h_details.h_rsa = *h_rsa; 194 hd->sm_sig = *sm_sig; 195 GNUNET_assert (GNUNET_CRYPTO_BSA_RSA == bs_pub->cipher); 196 hd->denom_pub.bsign_pub_key = 197 GNUNET_CRYPTO_bsign_pub_incref (bs_pub); 198 /* load the age mask for the denomination, if applicable */ 199 hd->denom_pub.age_mask = TEH_CONFIG_load_age_mask (section_name); 200 TALER_denom_pub_hash (&hd->denom_pub, 201 &hd->h_denom_pub); 202 hd->section_name = GNUNET_strdup (section_name); 203 GNUNET_assert ( 204 GNUNET_OK == 205 GNUNET_CONTAINER_multihashmap_put ( 206 denom_keys, 207 &hd->h_denom_pub.hash, 208 hd, 209 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 210 GNUNET_assert ( 211 GNUNET_OK == 212 GNUNET_CONTAINER_multihashmap_put ( 213 rsa_keys, 214 &hd->h_details.h_rsa.hash, 215 hd, 216 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 217 } 218 219 220 /** 221 * Check that the given CS security module's public key is the one 222 * we have pinned. If it does not match, we die hard. 223 * 224 * @param sm_pub RSA security module public key to check 225 */ 226 static void 227 check_denom_cs_sm_pub (const struct TALER_SecurityModulePublicKeyP *sm_pub) 228 { 229 if (0 != 230 GNUNET_memcmp (sm_pub, 231 &denom_cs_sm_pub)) 232 { 233 if (! GNUNET_is_zero (&denom_cs_sm_pub)) 234 { 235 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 236 "Our CS security module changed its key. This must not happen.\n"); 237 GNUNET_assert (0); 238 } 239 denom_cs_sm_pub = *sm_pub; /* TOFU ;-) */ 240 } 241 } 242 243 244 /** 245 * Function called with information about available CS keys for signing. Usually 246 * only called once per key upon connect. Also called again in case a key is 247 * being revoked, in that case with an @a end_time of zero. 248 * 249 * @param cls NULL 250 * @param section_name name of the denomination type in the configuration; 251 * NULL if the key has been revoked or purged 252 * @param start_time when does the key become available for signing; 253 * zero if the key has been revoked or purged 254 * @param validity_duration how long does the key remain available for signing; 255 * zero if the key has been revoked or purged 256 * @param h_cs hash of the @a denom_pub that is available (or was purged) 257 * @param bs_pub the public key itself, NULL if the key was revoked or purged 258 * @param sm_pub public key of the security module, NULL if the key was revoked or purged 259 * @param sm_sig signature from the security module 260 */ 261 static void 262 helper_cs_cb ( 263 void *cls, 264 const char *section_name, 265 struct GNUNET_TIME_Timestamp start_time, 266 struct GNUNET_TIME_Relative validity_duration, 267 const struct TALER_CsPubHashP *h_cs, 268 struct GNUNET_CRYPTO_BlindSignPublicKey *bs_pub, 269 const struct TALER_SecurityModulePublicKeyP *sm_pub, 270 const struct TALER_SecurityModuleSignatureP *sm_sig) 271 { 272 struct HelperDenomination *hd; 273 274 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 275 "CS helper announces key %s for denomination type %s with validity %s\n", 276 GNUNET_h2s (&h_cs->hash), 277 section_name, 278 GNUNET_STRINGS_relative_time_to_string (validity_duration, 279 GNUNET_NO)); 280 TEH_keys_bump_generation (); 281 TEH_resume_keys_requests (false); 282 hd = GNUNET_CONTAINER_multihashmap_get (cs_keys, 283 &h_cs->hash); 284 if (NULL != hd) 285 { 286 /* should be just an update (revocation!), so update existing entry */ 287 hd->validity_duration = validity_duration; 288 return; 289 } 290 GNUNET_assert (NULL != sm_pub); 291 check_denom_cs_sm_pub (sm_pub); 292 hd = GNUNET_new (struct HelperDenomination); 293 hd->start_time = start_time; 294 hd->validity_duration = validity_duration; 295 hd->h_details.h_cs = *h_cs; 296 hd->sm_sig = *sm_sig; 297 GNUNET_assert (GNUNET_CRYPTO_BSA_CS == bs_pub->cipher); 298 hd->denom_pub.bsign_pub_key 299 = GNUNET_CRYPTO_bsign_pub_incref (bs_pub); 300 /* load the age mask for the denomination, if applicable */ 301 hd->denom_pub.age_mask = TEH_CONFIG_load_age_mask (section_name); 302 TALER_denom_pub_hash (&hd->denom_pub, 303 &hd->h_denom_pub); 304 hd->section_name = GNUNET_strdup (section_name); 305 GNUNET_assert ( 306 GNUNET_OK == 307 GNUNET_CONTAINER_multihashmap_put ( 308 denom_keys, 309 &hd->h_denom_pub.hash, 310 hd, 311 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 312 GNUNET_assert ( 313 GNUNET_OK == 314 GNUNET_CONTAINER_multihashmap_put ( 315 cs_keys, 316 &hd->h_details.h_cs.hash, 317 hd, 318 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 319 } 320 321 322 /** 323 * Check that the given EdDSA security module's public key is the one 324 * we have pinned. If it does not match, we die hard. 325 * 326 * @param sm_pub EdDSA security module public key to check 327 */ 328 static void 329 check_esign_sm_pub (const struct TALER_SecurityModulePublicKeyP *sm_pub) 330 { 331 if (0 != 332 GNUNET_memcmp (sm_pub, 333 &esign_sm_pub)) 334 { 335 if (! GNUNET_is_zero (&esign_sm_pub)) 336 { 337 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 338 "Our EdDSA security module changed its key. This must not happen.\n"); 339 GNUNET_assert (0); 340 } 341 esign_sm_pub = *sm_pub; /* TOFU ;-) */ 342 } 343 } 344 345 346 /** 347 * Function called with information about available keys for signing. Usually 348 * only called once per key upon connect. Also called again in case a key is 349 * being revoked, in that case with an @a end_time of zero. 350 * 351 * @param cls NULL 352 * @param start_time when does the key become available for signing; 353 * zero if the key has been revoked or purged 354 * @param validity_duration how long does the key remain available for signing; 355 * zero if the key has been revoked or purged 356 * @param exchange_pub the public key itself, NULL if the key was revoked or purged 357 * @param sm_pub public key of the security module, NULL if the key was revoked or purged 358 * @param sm_sig signature from the security module 359 */ 360 static void 361 helper_esign_cb ( 362 void *cls, 363 struct GNUNET_TIME_Timestamp start_time, 364 struct GNUNET_TIME_Relative validity_duration, 365 const struct TALER_ExchangePublicKeyP *exchange_pub, 366 const struct TALER_SecurityModulePublicKeyP *sm_pub, 367 const struct TALER_SecurityModuleSignatureP *sm_sig) 368 { 369 struct HelperSignkey *hsk; 370 struct GNUNET_PeerIdentity pid; 371 372 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 373 "EdDSA helper announces signing key %s with validity %s\n", 374 TALER_B2S (exchange_pub), 375 GNUNET_STRINGS_relative_time_to_string (validity_duration, 376 GNUNET_NO)); 377 TEH_keys_bump_generation (); 378 TEH_resume_keys_requests (false); 379 pid.public_key = exchange_pub->eddsa_pub; 380 hsk = GNUNET_CONTAINER_multipeermap_get (esign_keys, 381 &pid); 382 if (NULL != hsk) 383 { 384 /* should be just an update (revocation!), so update existing entry */ 385 hsk->validity_duration = validity_duration; 386 return; 387 } 388 GNUNET_assert (NULL != sm_pub); 389 check_esign_sm_pub (sm_pub); 390 hsk = GNUNET_new (struct HelperSignkey); 391 hsk->start_time = start_time; 392 hsk->validity_duration = validity_duration; 393 hsk->exchange_pub = *exchange_pub; 394 hsk->sm_sig = *sm_sig; 395 GNUNET_assert ( 396 GNUNET_OK == 397 GNUNET_CONTAINER_multipeermap_put ( 398 esign_keys, 399 &pid, 400 hsk, 401 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 402 } 403 404 405 enum GNUNET_GenericReturnValue 406 TEH_SECMOD_setup_key_helpers () 407 { 408 if (GNUNET_OK != 409 GNUNET_CONFIGURATION_get_value_time (TEH_cfg, 410 "exchange", 411 "SIGNKEY_LEGAL_DURATION", 412 &signkey_legal_duration)) 413 { 414 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, 415 "exchange", 416 "SIGNKEY_LEGAL_DURATION"); 417 return GNUNET_SYSERR; 418 } 419 denom_keys 420 = GNUNET_CONTAINER_multihashmap_create (1024, 421 GNUNET_YES); 422 rsa_keys 423 = GNUNET_CONTAINER_multihashmap_create (1024, 424 GNUNET_YES); 425 cs_keys 426 = GNUNET_CONTAINER_multihashmap_create (1024, 427 GNUNET_YES); 428 esign_keys 429 = GNUNET_CONTAINER_multipeermap_create (32, 430 GNUNET_NO /* MUST BE NO! */); 431 rsadh = TALER_CRYPTO_helper_rsa_connect (TEH_cfg, 432 "taler-exchange", 433 &helper_rsa_cb, 434 NULL); 435 if (NULL == rsadh) 436 return GNUNET_SYSERR; 437 csdh = TALER_CRYPTO_helper_cs_connect (TEH_cfg, 438 "taler-exchange", 439 &helper_cs_cb, 440 NULL); 441 if (NULL == csdh) 442 return GNUNET_SYSERR; 443 esh = TALER_CRYPTO_helper_esign_connect (TEH_cfg, 444 "taler-exchange", 445 &helper_esign_cb, 446 NULL); 447 if (NULL == esh) 448 return GNUNET_SYSERR; 449 return GNUNET_OK; 450 } 451 452 453 void 454 TEH_SECMOD_sync_key_helpers (void) 455 { 456 TALER_CRYPTO_helper_rsa_poll (rsadh); 457 TALER_CRYPTO_helper_cs_poll (csdh); 458 TALER_CRYPTO_helper_esign_poll (esh); 459 } 460 461 462 /** 463 * Helper function for #TEH_SECMOD_destroy_key_helpers to free all entries 464 * in the `denom_keys` map. 465 * 466 * @param cls NULL 467 * @param h_denom_pub hash of the denomination public key 468 * @param value the `struct HelperDenomination` to release 469 * @return #GNUNET_OK (continue to iterate) 470 */ 471 static enum GNUNET_GenericReturnValue 472 free_denom_cb (void *cls, 473 const struct GNUNET_HashCode *h_denom_pub, 474 void *value) 475 { 476 struct HelperDenomination *hd = value; 477 478 (void) cls; 479 (void) h_denom_pub; 480 TALER_denom_pub_free (&hd->denom_pub); 481 GNUNET_free (hd->section_name); 482 GNUNET_free (hd); 483 return GNUNET_OK; 484 } 485 486 487 /** 488 * Helper function for #TEH_SECMOD_destroy_key_helpers to free all entries 489 * in the `esign_keys` map. 490 * 491 * @param cls NULL 492 * @param pid unused, matches the exchange public key 493 * @param value the `struct HelperSignkey` to release 494 * @return #GNUNET_OK (continue to iterate) 495 */ 496 static enum GNUNET_GenericReturnValue 497 free_esign_cb (void *cls, 498 const struct GNUNET_PeerIdentity *pid, 499 void *value) 500 { 501 struct HelperSignkey *hsk = value; 502 503 (void) cls; 504 (void) pid; 505 GNUNET_free (hsk); 506 return GNUNET_OK; 507 } 508 509 510 void 511 TEH_SECMOD_destroy_key_helpers () 512 { 513 GNUNET_CONTAINER_multihashmap_iterate (denom_keys, 514 &free_denom_cb, 515 NULL); 516 GNUNET_CONTAINER_multihashmap_destroy (rsa_keys); 517 rsa_keys = NULL; 518 GNUNET_CONTAINER_multihashmap_destroy (cs_keys); 519 cs_keys = NULL; 520 GNUNET_CONTAINER_multihashmap_destroy (denom_keys); 521 denom_keys = NULL; 522 GNUNET_CONTAINER_multipeermap_iterate (esign_keys, 523 &free_esign_cb, 524 NULL); 525 GNUNET_CONTAINER_multipeermap_destroy (esign_keys); 526 esign_keys = NULL; 527 if (NULL != rsadh) 528 { 529 TALER_CRYPTO_helper_rsa_disconnect (rsadh); 530 rsadh = NULL; 531 } 532 if (NULL != csdh) 533 { 534 TALER_CRYPTO_helper_cs_disconnect (csdh); 535 csdh = NULL; 536 } 537 if (NULL != esh) 538 { 539 TALER_CRYPTO_helper_esign_disconnect (esh); 540 esh = NULL; 541 } 542 } 543 544 545 void 546 TEH_SECMOD_iterate_denom_keys ( 547 GNUNET_CONTAINER_MultiHashMapIteratorCallback cb, 548 void *cb_cls) 549 { 550 GNUNET_CONTAINER_multihashmap_iterate (denom_keys, 551 cb, 552 cb_cls); 553 } 554 555 556 void 557 TEH_SECMOD_iterate_esign_keys ( 558 GNUNET_CONTAINER_PeerMapIterator cb, 559 void *cb_cls) 560 { 561 GNUNET_CONTAINER_multipeermap_iterate (esign_keys, 562 cb, 563 cb_cls); 564 565 } 566 567 568 enum TALER_ErrorCode 569 TEH_SECMOD_denom_cs_batch_r_pub_simple ( 570 unsigned int cdds_length, 571 const struct TEH_SECMOD_CsDeriveData cdds[static cdds_length], 572 bool for_melt, 573 struct GNUNET_CRYPTO_CSPublicRPairP r_pubs[static cdds_length]) 574 { 575 struct HelperDenomination *hd; 576 struct TALER_CRYPTO_CsDeriveRequest cdrs[cdds_length]; 577 578 for (unsigned int i = 0; i<cdds_length; i++) 579 { 580 const struct TALER_DenominationHashP *h_denom_pub = cdds[i].h_denom_pub; 581 const struct GNUNET_CRYPTO_CsSessionNonce *nonce = cdds[i].nonce; 582 583 hd = GNUNET_CONTAINER_multihashmap_get (denom_keys, 584 &h_denom_pub->hash); 585 if (NULL == hd) 586 { 587 return TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN; 588 } 589 if (GNUNET_CRYPTO_BSA_CS != 590 hd->denom_pub.bsign_pub_key->cipher) 591 { 592 return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; 593 } 594 cdrs[i].h_cs = &hd->h_details.h_cs; 595 cdrs[i].nonce = nonce; 596 } 597 598 return TALER_CRYPTO_helper_cs_r_batch_derive (csdh, 599 cdds_length, 600 cdrs, 601 for_melt, 602 r_pubs); 603 } 604 605 606 enum TALER_ErrorCode 607 TEH_SECMOD_denom_cs_batch_r_pub ( 608 size_t num, 609 const struct TALER_DenominationHashP h_denom_pubs[static num], 610 const struct GNUNET_CRYPTO_CsSessionNonce nonces[static num], 611 bool for_melt, 612 struct GNUNET_CRYPTO_CSPublicRPairP r_pubs[static num], 613 size_t *err_idx) 614 { 615 struct TALER_CRYPTO_CsDeriveRequest cdrs[num]; 616 617 for (unsigned int i = 0; i<num; i++) 618 { 619 const struct TEH_DenominationKey *dk; 620 const struct HelperDenomination *hd; 621 622 *err_idx = i; 623 624 /* FIXME: right now we need both, 625 * TEH_DenominationKey and HelperDenomination, 626 * because only TEH_DenominationKey has .recoup_possible 627 */ 628 hd = GNUNET_CONTAINER_multihashmap_get (denom_keys, 629 &h_denom_pubs[i].hash); 630 dk = TEH_keys_denomination_by_hash (&h_denom_pubs[i], 631 NULL, 632 NULL); 633 if (NULL == hd) 634 return TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN; 635 636 GNUNET_assert (NULL != dk); 637 638 if (GNUNET_CRYPTO_BSA_CS != 639 hd->denom_pub.bsign_pub_key->cipher) 640 return TALER_EC_EXCHANGE_GENERIC_INVALID_DENOMINATION_CIPHER_FOR_OPERATION 641 ; 642 643 if (GNUNET_TIME_absolute_is_future (hd->start_time.abs_time)) 644 return TALER_EC_EXCHANGE_GENERIC_DENOMINATION_VALIDITY_IN_FUTURE; 645 if (dk->recoup_possible) 646 return TALER_EC_EXCHANGE_GENERIC_DENOMINATION_REVOKED; 647 if (GNUNET_TIME_relative_is_zero (hd->validity_duration)) 648 return TALER_EC_EXCHANGE_GENERIC_DENOMINATION_EXPIRED; 649 650 cdrs[i].h_cs = &hd->h_details.h_cs; 651 cdrs[i].nonce = &nonces[i]; 652 } 653 654 return TALER_CRYPTO_helper_cs_r_batch_derive (csdh, 655 num, 656 cdrs, 657 for_melt, 658 r_pubs); 659 } 660 661 662 enum TALER_ErrorCode 663 TEH_SECMOD_denom_batch_sign ( 664 unsigned int csds_length, 665 const struct TEH_SECMOD_CoinSignData csds[static csds_length], 666 bool for_melt, 667 struct TALER_BlindedDenominationSignature bss[static csds_length]) 668 { 669 struct HelperDenomination *hd; 670 struct TALER_CRYPTO_RsaSignRequest rsrs[csds_length]; 671 struct TALER_CRYPTO_CsSignRequest csrs[csds_length]; 672 struct TALER_BlindedDenominationSignature rs[csds_length]; 673 struct TALER_BlindedDenominationSignature cs[csds_length]; 674 unsigned int rsrs_pos = 0; 675 unsigned int csrs_pos = 0; 676 enum TALER_ErrorCode ec; 677 678 for (unsigned int i = 0; i<csds_length; i++) 679 { 680 const struct TALER_DenominationHashP *h_denom_pub = csds[i].h_denom_pub; 681 const struct TALER_BlindedPlanchet *bp = csds[i].bp; 682 683 hd = GNUNET_CONTAINER_multihashmap_get (denom_keys, 684 &h_denom_pub->hash); 685 if (NULL == hd) 686 return TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN; 687 if (bp->blinded_message->cipher != 688 hd->denom_pub.bsign_pub_key->cipher) 689 return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; 690 switch (hd->denom_pub.bsign_pub_key->cipher) 691 { 692 case GNUNET_CRYPTO_BSA_RSA: 693 rsrs[rsrs_pos].h_rsa = &hd->h_details.h_rsa; 694 rsrs[rsrs_pos].msg 695 = bp->blinded_message->details.rsa_blinded_message.blinded_msg; 696 rsrs[rsrs_pos].msg_size 697 = bp->blinded_message->details.rsa_blinded_message.blinded_msg_size; 698 rsrs_pos++; 699 break; 700 case GNUNET_CRYPTO_BSA_CS: 701 csrs[csrs_pos].h_cs = &hd->h_details.h_cs; 702 csrs[csrs_pos].blinded_planchet 703 = &bp->blinded_message->details.cs_blinded_message; 704 csrs_pos++; 705 break; 706 default: 707 return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; 708 } 709 } 710 711 if (0 != rsrs_pos) 712 { 713 memset (rs, 714 0, 715 sizeof (rs)); 716 } 717 if (0 != csrs_pos) 718 { 719 memset (cs, 720 0, 721 sizeof (cs)); 722 } 723 ec = TALER_EC_NONE; 724 if (0 != csrs_pos) 725 { 726 ec = TALER_CRYPTO_helper_cs_batch_sign ( 727 csdh, 728 csrs_pos, 729 csrs, 730 for_melt, 731 (0 == rsrs_pos) ? bss : cs); 732 if (TALER_EC_NONE != ec) 733 { 734 for (unsigned int i = 0; i<csrs_pos; i++) 735 TALER_blinded_denom_sig_free (&cs[i]); 736 return ec; 737 } 738 TEH_METRICS_num_signatures[TEH_MT_SIGNATURE_CS] += csrs_pos; 739 } 740 if (0 != rsrs_pos) 741 { 742 ec = TALER_CRYPTO_helper_rsa_batch_sign ( 743 rsadh, 744 rsrs_pos, 745 rsrs, 746 (0 == csrs_pos) ? bss : rs); 747 if (TALER_EC_NONE != ec) 748 { 749 for (unsigned int i = 0; i<csrs_pos; i++) 750 TALER_blinded_denom_sig_free (&cs[i]); 751 for (unsigned int i = 0; i<rsrs_pos; i++) 752 TALER_blinded_denom_sig_free (&rs[i]); 753 return ec; 754 } 755 TEH_METRICS_num_signatures[TEH_MT_SIGNATURE_RSA] += rsrs_pos; 756 } 757 758 if ( (0 != csrs_pos) && 759 (0 != rsrs_pos) ) 760 { 761 rsrs_pos = 0; 762 csrs_pos = 0; 763 for (unsigned int i = 0; i<csds_length; i++) 764 { 765 const struct TALER_BlindedPlanchet *bp = csds[i].bp; 766 767 switch (bp->blinded_message->cipher) 768 { 769 case GNUNET_CRYPTO_BSA_RSA: 770 bss[i] = rs[rsrs_pos++]; 771 break; 772 case GNUNET_CRYPTO_BSA_CS: 773 bss[i] = cs[csrs_pos++]; 774 break; 775 default: 776 GNUNET_assert (0); 777 } 778 } 779 } 780 return TALER_EC_NONE; 781 } 782 783 784 enum TALER_ErrorCode 785 TEH_SECMOD_exchange_sign ( 786 const struct GNUNET_CRYPTO_SignaturePurpose *purpose, 787 struct TALER_ExchangePublicKeyP *pub, 788 struct TALER_ExchangeSignatureP *sig) 789 { 790 return TALER_CRYPTO_helper_esign_sign_ (esh, 791 purpose, 792 pub, 793 sig); 794 } 795 796 797 enum GNUNET_GenericReturnValue 798 TEH_SECMOD_denom_load_meta ( 799 const struct TALER_DenominationHashP *h_denom_pub, 800 struct TALER_DenominationPublicKey *denom_pub, 801 struct TALER_EXCHANGEDB_DenominationKeyMetaData *meta) 802 { 803 struct HelperDenomination *hd; 804 enum GNUNET_GenericReturnValue ok; 805 806 hd = GNUNET_CONTAINER_multihashmap_get (denom_keys, 807 &h_denom_pub->hash); 808 if (NULL == hd) 809 { 810 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 811 "Denomination %s not known\n", 812 GNUNET_h2s (&h_denom_pub->hash)); 813 return GNUNET_NO; 814 } 815 meta->start = hd->start_time; 816 meta->expire_withdraw = GNUNET_TIME_absolute_to_timestamp ( 817 GNUNET_TIME_absolute_add (meta->start.abs_time, 818 hd->validity_duration)); 819 ok = TEH_CONFIG_load_denom_data (hd->section_name, 820 meta); 821 if (GNUNET_OK == ok) 822 { 823 GNUNET_assert (GNUNET_CRYPTO_BSA_INVALID != 824 hd->denom_pub.bsign_pub_key->cipher); 825 TALER_denom_pub_copy (denom_pub, 826 &hd->denom_pub); 827 } 828 else 829 { 830 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 831 "No fees for `%s', voiding key\n", 832 hd->section_name); 833 memset (denom_pub, 834 0, 835 sizeof (*denom_pub)); 836 } 837 return ok; 838 } 839 840 841 enum GNUNET_GenericReturnValue 842 TEH_SECMOD_esign_load_meta (const struct TALER_ExchangePublicKeyP *exchange_pub, 843 struct TALER_EXCHANGEDB_SignkeyMetaData *meta) 844 { 845 struct HelperSignkey *hsk; 846 struct GNUNET_PeerIdentity pid; 847 848 pid.public_key = exchange_pub->eddsa_pub; 849 hsk = GNUNET_CONTAINER_multipeermap_get (esign_keys, 850 &pid); 851 if (NULL == hsk) 852 { 853 GNUNET_break (0); 854 return GNUNET_NO; 855 } 856 meta->start = hsk->start_time; 857 858 meta->expire_sign = GNUNET_TIME_absolute_to_timestamp ( 859 GNUNET_TIME_absolute_add (meta->start.abs_time, 860 hsk->validity_duration)); 861 meta->expire_legal = GNUNET_TIME_absolute_to_timestamp ( 862 GNUNET_TIME_absolute_add (meta->expire_sign.abs_time, 863 signkey_legal_duration)); 864 return GNUNET_OK; 865 } 866 867 868 bool 869 TEH_SECMOD_denom_priv_check_lost ( 870 const struct TALER_DenominationHashP *h_denom_pub) 871 { 872 struct HelperDenomination *hd; 873 874 hd = GNUNET_CONTAINER_multihashmap_get (denom_keys, 875 &h_denom_pub->hash); 876 return (NULL == hd) || 877 GNUNET_TIME_absolute_is_past ( 878 GNUNET_TIME_absolute_add ( 879 hd->start_time.abs_time, 880 hd->validity_duration)); 881 } 882 883 884 void 885 TEH_SECMOD_esign_revoke ( 886 const struct TALER_ExchangePublicKeyP *exchange_pub) 887 { 888 TALER_CRYPTO_helper_esign_revoke (esh, 889 exchange_pub); 890 TEH_keys_update_states (); 891 } 892 893 894 void 895 TEH_SECMOD_denom_revoke ( 896 const struct TALER_DenominationHashP *h_denom_pub) 897 { 898 struct HelperDenomination *hd; 899 900 hd = GNUNET_CONTAINER_multihashmap_get (denom_keys, 901 &h_denom_pub->hash); 902 if (NULL == hd) 903 { 904 GNUNET_break (0); 905 return; 906 } 907 switch (hd->denom_pub.bsign_pub_key->cipher) 908 { 909 case GNUNET_CRYPTO_BSA_INVALID: 910 break; 911 case GNUNET_CRYPTO_BSA_RSA: 912 TALER_CRYPTO_helper_rsa_revoke (rsadh, 913 &hd->h_details.h_rsa); 914 TEH_keys_update_states (); 915 return; 916 case GNUNET_CRYPTO_BSA_CS: 917 TALER_CRYPTO_helper_cs_revoke (csdh, 918 &hd->h_details.h_cs); 919 TEH_keys_update_states (); 920 return; 921 } 922 GNUNET_break (0); 923 return; 924 }