taler-exchange-httpd_keys.h (18861B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2020-2022 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_keys.h 18 * @brief management of our various keys 19 * @defgroup crypto Cryptographic routines 20 * @author Christian Grothoff 21 */ 22 #include "taler/platform.h" 23 #include "taler/taler_json_lib.h" 24 #include "taler/taler_mhd_lib.h" 25 #include "taler-exchange-httpd_responses.h" 26 27 28 #ifndef TALER_EXCHANGE_HTTPD_KEYS_H 29 #define TALER_EXCHANGE_HTTPD_KEYS_H 30 31 /** 32 * Signatures of an auditor over a denomination key of this exchange. 33 */ 34 struct TEH_AuditorSignature; 35 36 37 /** 38 * @brief All information about a denomination key (which is used to 39 * sign coins into existence). 40 */ 41 struct TEH_DenominationKey 42 { 43 44 /** 45 * Decoded denomination public key (the hash of it is in 46 * @e issue, but we sometimes need the full public key as well). 47 */ 48 struct TALER_DenominationPublicKey denom_pub; 49 50 /** 51 * Hash code of the denomination public key. 52 */ 53 struct TALER_DenominationHashP h_denom_pub; 54 55 /** 56 * Meta data about the type of the denomination, such as fees and validity 57 * periods. 58 */ 59 struct TALER_EXCHANGEDB_DenominationKeyMetaData meta; 60 61 /** 62 * The long-term offline master key's signature for this denomination. 63 * Signs over @e h_denom_pub and @e meta. 64 */ 65 struct TALER_MasterSignatureP master_sig; 66 67 /** 68 * We store the auditor signatures for this denomination in a DLL. 69 */ 70 struct TEH_AuditorSignature *as_head; 71 72 /** 73 * We store the auditor signatures for this denomination in a DLL. 74 */ 75 struct TEH_AuditorSignature *as_tail; 76 77 /** 78 * Set to 'true' if this denomination has been revoked and recoup is 79 * thus supported right now. 80 */ 81 bool recoup_possible; 82 83 }; 84 85 86 /** 87 * Set of global fees (and options) for a time range. 88 */ 89 struct TEH_GlobalFee 90 { 91 /** 92 * Kept in a DLL. 93 */ 94 struct TEH_GlobalFee *next; 95 96 /** 97 * Kept in a DLL. 98 */ 99 struct TEH_GlobalFee *prev; 100 101 /** 102 * Beginning of the validity period (inclusive). 103 */ 104 struct GNUNET_TIME_Timestamp start_date; 105 106 /** 107 * End of the validity period (exclusive). 108 */ 109 struct GNUNET_TIME_Timestamp end_date; 110 111 /** 112 * How long do unmerged purses stay around at most? 113 */ 114 struct GNUNET_TIME_Relative purse_timeout; 115 116 /** 117 * What is the longest history we return? 118 */ 119 struct GNUNET_TIME_Relative history_expiration; 120 121 /** 122 * Signature affirming these details. 123 */ 124 struct TALER_MasterSignatureP master_sig; 125 126 /** 127 * Fee structure for operations that do not depend 128 * on a denomination or wire method. 129 */ 130 struct TALER_GlobalFeeSet fees; 131 132 /** 133 * Number of free purses per account. 134 */ 135 uint32_t purse_account_limit; 136 }; 137 138 139 /** 140 * Snapshot of the (coin and signing) keys (including private keys) of 141 * the exchange. There can be multiple instances of this struct, as it is 142 * reference counted and only destroyed once the last user is done 143 * with it. The current instance is acquired using 144 * #TEH_KS_acquire(). Using this function increases the 145 * reference count. The contents of this structure (except for the 146 * reference counter) should be considered READ-ONLY until it is 147 * ultimately destroyed (as there can be many concurrent users). 148 */ 149 struct TEH_KeyStateHandle; 150 151 152 /** 153 * Run internal invariant checks. For debugging. 154 */ 155 void 156 TEH_check_invariants (void); 157 158 159 /** 160 * Look up wire fee structure by @a ts. 161 * 162 * @param ts timestamp to lookup wire fees at 163 * @param method wire method to lookup fees for 164 * @return the wire fee details, or 165 * NULL if none are configured for @a ts and @a method 166 */ 167 const struct TALER_WireFeeSet * 168 TEH_wire_fees_by_time ( 169 struct GNUNET_TIME_Timestamp ts, 170 const char *method); 171 172 173 /** 174 * Something changed in the database. Rebuild the wire replies. This function 175 * should be called if the exchange learns about a new signature from our 176 * master key. 177 * 178 * (We do not do so immediately, but merely signal to all threads that they 179 * need to rebuild their wire state upon the next call to 180 * #TEH_keys_get_state()). 181 */ 182 void 183 TEH_wire_update_state (void); 184 185 186 /** 187 * Return the current key state for this thread. Possibly re-builds the key 188 * state if we have reason to believe that something changed. 189 * 190 * The result is ONLY valid until the next call to 191 * #TEH_keys_denomination_by_hash() or #TEH_keys_get_state() 192 * or #TEH_keys_exchange_sign(). 193 * 194 * @return NULL on error 195 */ 196 struct TEH_KeyStateHandle * 197 TEH_keys_get_state (void); 198 199 /** 200 * Obtain the key state if we should NOT run finish_keys_response() because we 201 * only need the state for the /management/keys API 202 */ 203 struct TEH_KeyStateHandle * 204 TEH_keys_get_state_for_management_only (void); 205 206 /** 207 * Something changed in the database. Rebuild all key states. This function 208 * should be called if the exchange learns about a new signature from an 209 * auditor or our master key. 210 * 211 * (We do not do so immediately, but merely signal to all threads that they 212 * need to rebuild their key state upon the next call to 213 * #TEH_keys_get_state()). 214 */ 215 void 216 TEH_keys_update_states (void); 217 218 219 /** 220 * Look up global fee structure by @a ts. 221 * 222 * @param ksh key state state to look in 223 * @param ts timestamp to lookup global fees at 224 * @return the global fee details, or 225 * NULL if none are configured for @a ts 226 */ 227 const struct TEH_GlobalFee * 228 TEH_keys_global_fee_by_time ( 229 struct TEH_KeyStateHandle *ksh, 230 struct GNUNET_TIME_Timestamp ts); 231 232 233 /** 234 * Look up the issue for a denom public key. Note that the result 235 * must only be used in this thread and only until another key or 236 * key state is resolved. 237 * 238 * @param h_denom_pub hash of denomination public key 239 * @param[in,out] conn used to return status message if NULL is returned 240 * @param[out] mret set to the MHD status if NULL is returned 241 * @return the denomination key issue, 242 * or NULL if @a h_denom_pub could not be found 243 */ 244 struct TEH_DenominationKey * 245 TEH_keys_denomination_by_hash ( 246 const struct TALER_DenominationHashP *h_denom_pub, 247 struct MHD_Connection *conn, 248 MHD_RESULT *mret); 249 250 251 /** 252 * Look up the issue for a denom public key using a given @a ksh. This allows 253 * requesting multiple denominations with the same @a ksh which thus will 254 * remain valid until the next call to #TEH_keys_denomination_by_hash() or 255 * #TEH_keys_get_state() or #TEH_keys_exchange_sign(). 256 * 257 * @param ksh key state state to look in 258 * @param h_denom_pub hash of denomination public key 259 * @param[in,out] conn connection used to return status message if NULL is returned 260 * @param[out] mret set to the MHD status if NULL is returned 261 * @return the denomination key issue, 262 * or NULL if @a h_denom_pub could not be found 263 */ 264 struct TEH_DenominationKey * 265 TEH_keys_denomination_by_hash_from_state ( 266 const struct TEH_KeyStateHandle *ksh, 267 const struct TALER_DenominationHashP *h_denom_pub, 268 struct MHD_Connection *conn, 269 MHD_RESULT *mret); 270 271 272 /** 273 * Look up the issue for a denom public key using a given @a ksh. This allows 274 * requesting multiple denominations with the same @a ksh which thus will 275 * remain valid until the next call to #TEH_keys_denomination_by_hash() or 276 * #TEH_keys_get_state() or #TEH_keys_exchange_sign(). 277 * 278 * @param ksh key state state to look in 279 * @param denom_serial serial ID of the denomination in the table 280 * @return the denomination key issue, 281 * or NULL if @a denom_serial could not be found 282 */ 283 struct TEH_DenominationKey * 284 TEH_keys_denomination_by_serial_from_state ( 285 const struct TEH_KeyStateHandle *ksh, 286 uint64_t denom_serial); 287 288 289 /** 290 * Information needed to create a blind signature. 291 */ 292 struct TEH_CoinSignData 293 { 294 /** 295 * Hash of key to sign with. 296 */ 297 const struct TALER_DenominationHashP *h_denom_pub; 298 299 /** 300 * Blinded planchet to sign over. 301 */ 302 const struct TALER_BlindedPlanchet *bp; 303 }; 304 305 306 /** 307 * Request to sign @a csds. 308 * 309 * @param csds array with data to blindly sign (and keys to sign with) 310 * @param csds_length length of @a csds array 311 * @param for_melt true if this is for a melt operation 312 * @param[out] bss array set to the blind signature on success; must be of length @a csds_length 313 * @return #TALER_EC_NONE on success 314 */ 315 enum TALER_ErrorCode 316 TEH_keys_denomination_batch_sign ( 317 unsigned int csds_length, 318 const struct TEH_CoinSignData csds[static csds_length], 319 bool for_melt, 320 struct TALER_BlindedDenominationSignature bss[static csds_length]); 321 322 323 /** 324 * Information needed to derive the CS r_pub. 325 */ 326 struct TEH_CsDeriveData 327 { 328 /** 329 * Hash of key to sign with. 330 */ 331 const struct TALER_DenominationHashP *h_denom_pub; 332 333 /** 334 * Nonce to use. 335 */ 336 const struct GNUNET_CRYPTO_CsSessionNonce *nonce; 337 }; 338 339 340 /** 341 * Request to derive CS @a r_pub using the denomination and nonce from @a cdd. 342 * 343 * @param cdd data to compute @a r_pub from 344 * @param for_melt true if this is for a melt operation 345 * @param[out] r_pub where to write the result 346 * @return #TALER_EC_NONE on success 347 */ 348 enum TALER_ErrorCode 349 TEH_keys_denomination_cs_r_pub ( 350 const struct TEH_CsDeriveData *cdd, 351 bool for_melt, 352 struct GNUNET_CRYPTO_CSPublicRPairP *r_pub); 353 354 355 /** 356 * Request to derive a bunch of CS @a r_pubs using the 357 * denominations and nonces from @a cdds. 358 * 359 * @param cdds array to compute @a r_pubs from 360 * @param cdds_length length of the @a cdds array 361 * @param for_melt true if this is for a melt operation 362 * @param[out] r_pubs array where to write the result; must be of length @a cdds_length 363 * @return #TALER_EC_NONE on success 364 */ 365 enum TALER_ErrorCode 366 TEH_keys_denomination_cs_batch_r_pub_simple ( 367 unsigned int cdds_length, 368 const struct TEH_CsDeriveData cdds[static cdds_length], 369 bool for_melt, 370 struct GNUNET_CRYPTO_CSPublicRPairP r_pubs[static cdds_length]); 371 372 373 /** 374 * Request to derive a bunch of CS @a r_pubs using the 375 * denominations and nonces from @a cdds. 376 * 377 * @param ksh keys state to load the keys from 378 * @param num number of input elements 379 * @param h_denom_pubs array @a num of hashes of keys to sign with 380 * @param nonces array @a num of nonces to use 381 * @param for_melt true if this is for a melt operation 382 * @param[out] r_pubs array where to write the result; must be of length @a num 383 * @param[out] err_idx in case of error, the index into @e cdds that caused it 384 * @return #TALER_EC_NONE on success 385 */ 386 enum TALER_ErrorCode 387 TEH_keys_denomination_cs_batch_r_pub ( 388 const struct TEH_KeyStateHandle *ksh, 389 size_t num, 390 const struct TALER_DenominationHashP h_denom_pubs[static num], 391 const struct GNUNET_CRYPTO_CsSessionNonce nonces[static num], 392 bool for_melt, 393 struct GNUNET_CRYPTO_CSPublicRPairP r_pubs[static num], 394 size_t *err_idx); 395 396 /** 397 * Revoke the public key associated with @a h_denom_pub. 398 * This function should be called AFTER the database was 399 * updated, as it also triggers #TEH_keys_update_states(). 400 * 401 * Note that the actual revocation happens asynchronously and 402 * may thus fail silently. To verify that the revocation succeeded, 403 * clients must watch for the associated change to the key state. 404 * 405 * @param h_denom_pub hash of the public key to revoke 406 */ 407 void 408 TEH_keys_denomination_revoke ( 409 const struct TALER_DenominationHashP *h_denom_pub); 410 411 412 /** 413 * Fully clean up keys subsystem. 414 */ 415 void 416 TEH_keys_finished (void); 417 418 419 /** 420 * Resumes all suspended /keys requests, we may now have key material 421 * (or are shutting down). 422 * 423 * @param do_shutdown are we shutting down? 424 */ 425 void 426 TEH_resume_keys_requests (bool do_shutdown); 427 428 429 /** 430 * Sign the message in @a purpose with the exchange's signing key. 431 * 432 * The @a purpose data is the beginning of the data of which the signature is 433 * to be created. The `size` field in @a purpose must correctly indicate the 434 * number of bytes of the data structure, including its header. Use 435 * #TEH_keys_exchange_sign() instead of calling this function directly! 436 * 437 * @param purpose the message to sign 438 * @param[out] pub set to the current public signing key of the exchange 439 * @param[out] sig signature over purpose using current signing key 440 * @return #TALER_EC_NONE on success 441 */ 442 enum TALER_ErrorCode 443 TEH_keys_exchange_sign_ ( 444 const struct GNUNET_CRYPTO_SignaturePurpose *purpose, 445 struct TALER_ExchangePublicKeyP *pub, 446 struct TALER_ExchangeSignatureP *sig); 447 448 449 /** 450 * Sign the message in @a purpose with the exchange's signing key. 451 * 452 * The @a purpose data is the beginning of the data of which the signature is 453 * to be created. The `size` field in @a purpose must correctly indicate the 454 * number of bytes of the data structure, including its header. Use 455 * #TEH_keys_exchange_sign() instead of calling this function directly! 456 * 457 * @param cls key state state to look in 458 * @param purpose the message to sign 459 * @param[out] pub set to the current public signing key of the exchange 460 * @param[out] sig signature over purpose using current signing key 461 * @return #TALER_EC_NONE on success 462 */ 463 enum TALER_ErrorCode 464 TEH_keys_exchange_sign2_ ( 465 void *cls, 466 const struct GNUNET_CRYPTO_SignaturePurpose *purpose, 467 struct TALER_ExchangePublicKeyP *pub, 468 struct TALER_ExchangeSignatureP *sig); 469 470 471 /** 472 * @ingroup crypto 473 * @brief EdDSA sign a given block. 474 * 475 * The @a ps data must be a fixed-size struct for which the signature is to be 476 * created. The `size` field in @a ps->purpose must correctly indicate the 477 * number of bytes of the data structure, including its header. 478 * 479 * @param ps packed struct with what to sign, MUST begin with a purpose 480 * @param[out] pub where to store the public key to use for the signing 481 * @param[out] sig where to write the signature 482 * @return #TALER_EC_NONE on success 483 */ 484 #define TEH_keys_exchange_sign(ps,pub,sig) \ 485 ({ \ 486 /* check size is set correctly */ \ 487 GNUNET_assert (htonl ((ps)->purpose.size) == \ 488 sizeof (*ps)); \ 489 /* check 'ps' begins with the purpose */ \ 490 GNUNET_static_assert (((void*) (ps)) == \ 491 ((void*) &(ps)->purpose)); \ 492 TEH_keys_exchange_sign_ (&(ps)->purpose, \ 493 pub, \ 494 sig); \ 495 }) 496 497 498 /** 499 * @ingroup crypto 500 * @brief EdDSA sign a given block. 501 * 502 * The @a ps data must be a fixed-size struct for which the signature is to be 503 * created. The `size` field in @a ps->purpose must correctly indicate the 504 * number of bytes of the data structure, including its header. 505 * 506 * This allows requesting multiple denominations with the same @a ksh which 507 * thus will remain valid until the next call to 508 * #TEH_keys_denomination_by_hash() or #TEH_keys_get_state() or 509 * #TEH_keys_exchange_sign(). 510 * 511 * @param ksh key state to use 512 * @param ps packed struct with what to sign, MUST begin with a purpose 513 * @param[out] pub where to store the public key to use for the signing 514 * @param[out] sig where to write the signature 515 * @return #TALER_EC_NONE on success 516 */ 517 #define TEH_keys_exchange_sign2(ksh,ps,pub,sig) \ 518 ({ \ 519 /* check size is set correctly */ \ 520 GNUNET_assert (htonl ((ps)->purpose.size) == \ 521 sizeof (*ps)); \ 522 /* check 'ps' begins with the purpose */ \ 523 GNUNET_static_assert (((void*) (ps)) == \ 524 ((void*) &(ps)->purpose)); \ 525 TEH_keys_exchange_sign2_ (ksh, \ 526 &(ps)->purpose, \ 527 pub, \ 528 sig); \ 529 }) 530 531 532 /** 533 * Revoke the given exchange's signing key. 534 * This function should be called AFTER the database was 535 * updated, as it also triggers #TEH_keys_update_states(). 536 * 537 * Note that the actual revocation happens asynchronously and 538 * may thus fail silently. To verify that the revocation succeeded, 539 * clients must watch for the associated change to the key state. 540 * 541 * @param exchange_pub key to revoke 542 */ 543 void 544 TEH_keys_exchange_revoke (const struct TALER_ExchangePublicKeyP *exchange_pub); 545 546 547 /** 548 * Function to call to handle requests to "/keys" by sending 549 * back our current key material. 550 * 551 * @param rc request context 552 * @param args array of additional options (must be empty for this function) 553 * @return MHD result code 554 */ 555 MHD_RESULT 556 TEH_keys_get_handler (struct TEH_RequestContext *rc, 557 const char *const args[]); 558 559 560 /** 561 * Function to call to handle requests to "/management/keys" by sending 562 * back our future key material. 563 * 564 * @param rh context of the handler 565 * @param connection the MHD connection to handle 566 * @return MHD result code 567 */ 568 MHD_RESULT 569 TEH_keys_management_get_keys_handler (const struct TEH_RequestHandler *rh, 570 struct MHD_Connection *connection); 571 572 573 /** 574 * Load fees and expiration times (!) for the denomination type configured for 575 * the denomination matching @a h_denom_pub. 576 * 577 * @param ksh key state to load fees from 578 * @param h_denom_pub hash of the denomination public key 579 * to use to derive the section name of the configuration to use 580 * @param[out] denom_pub set to the denomination public key (to be freed by caller!) 581 * @param[out] meta denomination type data to complete 582 * @return #GNUNET_OK on success, 583 * #GNUNET_NO if @a h_denom_pub is not known 584 * #GNUNET_SYSERR on hard errors 585 */ 586 enum GNUNET_GenericReturnValue 587 TEH_keys_load_fees (struct TEH_KeyStateHandle *ksh, 588 const struct TALER_DenominationHashP *h_denom_pub, 589 struct TALER_DenominationPublicKey *denom_pub, 590 struct TALER_EXCHANGEDB_DenominationKeyMetaData *meta); 591 592 593 /** 594 * Load expiration times for the given onling signing key. 595 * 596 * @param exchange_pub the online signing key 597 * @param[out] meta set to meta data about the key 598 * @return #GNUNET_OK on success 599 */ 600 enum GNUNET_GenericReturnValue 601 TEH_keys_get_timing (const struct TALER_ExchangePublicKeyP *exchange_pub, 602 struct TALER_EXCHANGEDB_SignkeyMetaData *meta); 603 604 605 /** 606 * Initialize keys subsystem. 607 * 608 * @return #GNUNET_OK on success 609 */ 610 enum GNUNET_GenericReturnValue 611 TEH_keys_init (void); 612 613 614 #endif