exchange_signatures.c (53438B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2021-2025 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 exchange_signatures.c 18 * @brief Utility functions for Taler security module signatures 19 * @author Christian Grothoff 20 */ 21 #include "taler/platform.h" 22 #include "taler/taler_util.h" 23 #include "taler/taler_signatures.h" 24 25 26 GNUNET_NETWORK_STRUCT_BEGIN 27 28 /** 29 * @brief Format used to generate the signature on a confirmation 30 * from the exchange that a deposit request succeeded. 31 */ 32 struct TALER_DepositConfirmationPS 33 { 34 /** 35 * Purpose must be #TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT. Signed 36 * by a `struct TALER_ExchangePublicKeyP` using EdDSA. 37 */ 38 struct GNUNET_CRYPTO_SignaturePurpose purpose; 39 40 /** 41 * Hash over the contract for which this deposit is made. 42 */ 43 struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED; 44 45 /** 46 * Hash over the wiring information of the merchant. 47 */ 48 struct TALER_MerchantWireHashP h_wire GNUNET_PACKED; 49 50 /** 51 * Hash over the optional policy extension of the deposit, 0 if there 52 * was no policy. 53 */ 54 struct TALER_ExtensionPolicyHashP h_policy GNUNET_PACKED; 55 56 /** 57 * Time when this confirmation was generated / when the exchange received 58 * the deposit request. 59 */ 60 struct GNUNET_TIME_TimestampNBO exchange_timestamp; 61 62 /** 63 * By when does the exchange expect to pay the merchant 64 * (as per the merchant's request). 65 */ 66 struct GNUNET_TIME_TimestampNBO wire_deadline; 67 68 /** 69 * How much time does the @e merchant have to issue a refund 70 * request? Zero if refunds are not allowed. After this time, the 71 * coin cannot be refunded. Note that the wire transfer will not be 72 * performed by the exchange until the refund deadline. This value 73 * is taken from the original deposit request. 74 */ 75 struct GNUNET_TIME_TimestampNBO refund_deadline; 76 77 /** 78 * Amount to be deposited, excluding fee. Calculated from the 79 * amount with fee and the fee from the deposit request. 80 */ 81 struct TALER_AmountNBO total_without_fee; 82 83 /** 84 * Hash over all of the coin signatures. 85 */ 86 struct GNUNET_HashCode h_coin_sigs; 87 88 /** 89 * The Merchant's public key. Allows the merchant to later refund 90 * the transaction or to inquire about the wire transfer identifier. 91 */ 92 struct TALER_MerchantPublicKeyP merchant_pub; 93 94 }; 95 96 GNUNET_NETWORK_STRUCT_END 97 98 99 enum TALER_ErrorCode 100 TALER_exchange_online_deposit_confirmation_sign ( 101 TALER_ExchangeSignCallback scb, 102 const struct TALER_PrivateContractHashP *h_contract_terms, 103 const struct TALER_MerchantWireHashP *h_wire, 104 const struct TALER_ExtensionPolicyHashP *h_policy, 105 struct GNUNET_TIME_Timestamp exchange_timestamp, 106 struct GNUNET_TIME_Timestamp wire_deadline, 107 struct GNUNET_TIME_Timestamp refund_deadline, 108 const struct TALER_Amount *total_without_fee, 109 unsigned int num_coins, 110 const struct TALER_CoinSpendSignatureP *coin_sigs[static num_coins], 111 const struct TALER_MerchantPublicKeyP *merchant_pub, 112 struct TALER_ExchangePublicKeyP *pub, 113 struct TALER_ExchangeSignatureP *sig) 114 { 115 struct TALER_DepositConfirmationPS dcs = { 116 .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT), 117 .purpose.size = htonl (sizeof (struct TALER_DepositConfirmationPS)), 118 .h_contract_terms = *h_contract_terms, 119 .h_wire = *h_wire, 120 .exchange_timestamp = GNUNET_TIME_timestamp_hton (exchange_timestamp), 121 .wire_deadline = GNUNET_TIME_timestamp_hton (wire_deadline), 122 .refund_deadline = GNUNET_TIME_timestamp_hton (refund_deadline), 123 .merchant_pub = *merchant_pub, 124 .h_policy = {{{0}}} 125 }; 126 struct GNUNET_HashContext *hc; 127 128 hc = GNUNET_CRYPTO_hash_context_start (); 129 for (unsigned int i = 0; i<num_coins; i++) 130 GNUNET_CRYPTO_hash_context_read (hc, 131 coin_sigs[i], 132 sizeof (*coin_sigs[i])); 133 GNUNET_CRYPTO_hash_context_finish (hc, 134 &dcs.h_coin_sigs); 135 if (NULL != h_policy) 136 dcs.h_policy = *h_policy; 137 TALER_amount_hton (&dcs.total_without_fee, 138 total_without_fee); 139 return scb (&dcs.purpose, 140 pub, 141 sig); 142 } 143 144 145 enum GNUNET_GenericReturnValue 146 TALER_exchange_online_deposit_confirmation_verify ( 147 const struct TALER_PrivateContractHashP *h_contract_terms, 148 const struct TALER_MerchantWireHashP *h_wire, 149 const struct TALER_ExtensionPolicyHashP *h_policy, 150 struct GNUNET_TIME_Timestamp exchange_timestamp, 151 struct GNUNET_TIME_Timestamp wire_deadline, 152 struct GNUNET_TIME_Timestamp refund_deadline, 153 const struct TALER_Amount *total_without_fee, 154 unsigned int num_coins, 155 const struct TALER_CoinSpendSignatureP *coin_sigs[static num_coins], 156 const struct TALER_MerchantPublicKeyP *merchant_pub, 157 const struct TALER_ExchangePublicKeyP *exchange_pub, 158 const struct TALER_ExchangeSignatureP *exchange_sig) 159 { 160 struct TALER_DepositConfirmationPS dcs = { 161 .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT), 162 .purpose.size = htonl (sizeof (struct TALER_DepositConfirmationPS)), 163 .h_contract_terms = *h_contract_terms, 164 .h_wire = *h_wire, 165 .exchange_timestamp = GNUNET_TIME_timestamp_hton (exchange_timestamp), 166 .wire_deadline = GNUNET_TIME_timestamp_hton (wire_deadline), 167 .refund_deadline = GNUNET_TIME_timestamp_hton (refund_deadline), 168 .merchant_pub = *merchant_pub 169 }; 170 struct GNUNET_HashContext *hc; 171 172 hc = GNUNET_CRYPTO_hash_context_start (); 173 for (unsigned int i = 0; i<num_coins; i++) 174 GNUNET_CRYPTO_hash_context_read (hc, 175 coin_sigs[i], 176 sizeof (*coin_sigs[i])); 177 GNUNET_CRYPTO_hash_context_finish (hc, 178 &dcs.h_coin_sigs); 179 if (NULL != h_policy) 180 dcs.h_policy = *h_policy; 181 TALER_amount_hton (&dcs.total_without_fee, 182 total_without_fee); 183 if (GNUNET_OK != 184 GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT, 185 &dcs, 186 &exchange_sig->eddsa_signature, 187 &exchange_pub->eddsa_pub)) 188 { 189 GNUNET_break_op (0); 190 return GNUNET_SYSERR; 191 } 192 return GNUNET_OK; 193 } 194 195 196 GNUNET_NETWORK_STRUCT_BEGIN 197 198 /** 199 * @brief Format used to generate the signature on a request to refund 200 * a coin into the account of the customer. 201 */ 202 struct TALER_RefundConfirmationPS 203 { 204 /** 205 * Purpose must be #TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND. 206 */ 207 struct GNUNET_CRYPTO_SignaturePurpose purpose; 208 209 /** 210 * Hash over the proposal data to identify the contract 211 * which is being refunded. 212 */ 213 struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED; 214 215 /** 216 * The coin's public key. This is the value that must have been 217 * signed (blindly) by the Exchange. 218 */ 219 struct TALER_CoinSpendPublicKeyP coin_pub; 220 221 /** 222 * The Merchant's public key. Allows the merchant to later refund 223 * the transaction or to inquire about the wire transfer identifier. 224 */ 225 struct TALER_MerchantPublicKeyP merchant; 226 227 /** 228 * Merchant-generated transaction ID for the refund. 229 */ 230 uint64_t rtransaction_id GNUNET_PACKED; 231 232 /** 233 * Amount to be refunded, including refund fee charged by the 234 * exchange to the customer. 235 */ 236 struct TALER_AmountNBO refund_amount; 237 }; 238 239 GNUNET_NETWORK_STRUCT_END 240 241 242 enum TALER_ErrorCode 243 TALER_exchange_online_refund_confirmation_sign ( 244 TALER_ExchangeSignCallback scb, 245 const struct TALER_PrivateContractHashP *h_contract_terms, 246 const struct TALER_CoinSpendPublicKeyP *coin_pub, 247 const struct TALER_MerchantPublicKeyP *merchant, 248 uint64_t rtransaction_id, 249 const struct TALER_Amount *refund_amount, 250 struct TALER_ExchangePublicKeyP *pub, 251 struct TALER_ExchangeSignatureP *sig) 252 { 253 struct TALER_RefundConfirmationPS rc = { 254 .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND), 255 .purpose.size = htonl (sizeof (rc)), 256 .h_contract_terms = *h_contract_terms, 257 .coin_pub = *coin_pub, 258 .merchant = *merchant, 259 .rtransaction_id = GNUNET_htonll (rtransaction_id) 260 }; 261 262 TALER_amount_hton (&rc.refund_amount, 263 refund_amount); 264 return scb (&rc.purpose, 265 pub, 266 sig); 267 } 268 269 270 enum GNUNET_GenericReturnValue 271 TALER_exchange_online_refund_confirmation_verify ( 272 const struct TALER_PrivateContractHashP *h_contract_terms, 273 const struct TALER_CoinSpendPublicKeyP *coin_pub, 274 const struct TALER_MerchantPublicKeyP *merchant, 275 uint64_t rtransaction_id, 276 const struct TALER_Amount *refund_amount, 277 const struct TALER_ExchangePublicKeyP *pub, 278 const struct TALER_ExchangeSignatureP *sig) 279 { 280 struct TALER_RefundConfirmationPS rc = { 281 .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND), 282 .purpose.size = htonl (sizeof (rc)), 283 .h_contract_terms = *h_contract_terms, 284 .coin_pub = *coin_pub, 285 .merchant = *merchant, 286 .rtransaction_id = GNUNET_htonll (rtransaction_id) 287 }; 288 289 TALER_amount_hton (&rc.refund_amount, 290 refund_amount); 291 if (GNUNET_OK != 292 GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND, 293 &rc, 294 &sig->eddsa_signature, 295 &pub->eddsa_pub)) 296 { 297 GNUNET_break_op (0); 298 return GNUNET_SYSERR; 299 } 300 return GNUNET_OK; 301 } 302 303 304 GNUNET_NETWORK_STRUCT_BEGIN 305 306 /** 307 * @brief Format of the block signed by the Exchange in response to a successful 308 * "/refresh/melt" request. Hereby the exchange affirms that all of the 309 * coins were successfully melted. This also commits the exchange to a 310 * particular index to not be revealed during the refresh. 311 */ 312 struct TALER_RefreshMeltConfirmationPS 313 { 314 /** 315 * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT. Signed 316 * by a `struct TALER_ExchangePublicKeyP` using EdDSA. 317 */ 318 struct GNUNET_CRYPTO_SignaturePurpose purpose; 319 320 /** 321 * Commitment made in the /refresh/melt. 322 */ 323 struct TALER_RefreshCommitmentP rc GNUNET_PACKED; 324 325 /** 326 * Index that the client will not have to reveal, in NBO. 327 * Must be smaller than #TALER_CNC_KAPPA. 328 */ 329 uint32_t noreveal_index GNUNET_PACKED; 330 331 }; 332 333 GNUNET_NETWORK_STRUCT_END 334 335 336 enum TALER_ErrorCode 337 TALER_exchange_online_melt_confirmation_sign ( 338 TALER_ExchangeSignCallback scb, 339 const struct TALER_RefreshCommitmentP *rc, 340 uint32_t noreveal_index, 341 struct TALER_ExchangePublicKeyP *pub, 342 struct TALER_ExchangeSignatureP *sig) 343 { 344 struct TALER_RefreshMeltConfirmationPS confirm = { 345 .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT), 346 .purpose.size = htonl (sizeof (confirm)), 347 .rc = *rc, 348 .noreveal_index = htonl (noreveal_index) 349 }; 350 351 return scb (&confirm.purpose, 352 pub, 353 sig); 354 } 355 356 357 enum GNUNET_GenericReturnValue 358 TALER_exchange_online_melt_confirmation_verify ( 359 const struct TALER_RefreshCommitmentP *rc, 360 uint32_t noreveal_index, 361 const struct TALER_ExchangePublicKeyP *exchange_pub, 362 const struct TALER_ExchangeSignatureP *exchange_sig) 363 { 364 struct TALER_RefreshMeltConfirmationPS confirm = { 365 .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT), 366 .purpose.size = htonl (sizeof (confirm)), 367 .rc = *rc, 368 .noreveal_index = htonl (noreveal_index) 369 }; 370 371 return 372 GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT, 373 &confirm, 374 &exchange_sig->eddsa_signature, 375 &exchange_pub->eddsa_pub); 376 } 377 378 379 GNUNET_NETWORK_STRUCT_BEGIN 380 381 /** 382 * @brief Format of the block signed by the Exchange in response to a 383 * successful "/withdraw" request. 384 * If age restriction is set, the exchange hereby also 385 * affirms that the commitment along with the maximum age group and 386 * the amount were accepted. This also commits the exchange to a particular 387 * index to not be revealed during the reveal. 388 */ 389 struct TALER_WithdrawConfirmationPS 390 { 391 /** 392 * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_WITHDRAW. Signed by a 393 * `struct TALER_ExchangePublicKeyP` using EdDSA. 394 */ 395 struct GNUNET_CRYPTO_SignaturePurpose purpose; 396 397 /** 398 * Commitment made in the /withdraw call. 399 */ 400 struct TALER_HashBlindedPlanchetsP h_planchets GNUNET_PACKED; 401 402 /** 403 * If age restriction does not apply to this withdrawal, 404 * (i.e. max_age was not set during the request) 405 * MUST be 0xFFFFFFFF. 406 * Otherwise (i.e. age restriction applies): 407 * index that the client will not have to reveal, in NBO, 408 * MUST be smaller than #TALER_CNC_KAPPA. 409 */ 410 uint32_t noreveal_index GNUNET_PACKED; 411 412 }; 413 414 GNUNET_NETWORK_STRUCT_END 415 416 enum TALER_ErrorCode 417 TALER_exchange_online_withdraw_age_confirmation_sign ( 418 TALER_ExchangeSignCallback scb, 419 const struct TALER_HashBlindedPlanchetsP *h_planchets, 420 uint32_t noreveal_index, 421 struct TALER_ExchangePublicKeyP *pub, 422 struct TALER_ExchangeSignatureP *sig) 423 { 424 425 struct TALER_WithdrawConfirmationPS confirm = { 426 .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WITHDRAW), 427 .purpose.size = htonl (sizeof (confirm)), 428 .h_planchets = *h_planchets, 429 .noreveal_index = htonl (noreveal_index) 430 }; 431 432 return scb (&confirm.purpose, 433 pub, 434 sig); 435 } 436 437 438 enum TALER_ErrorCode 439 TALER_exchange_online_withdraw_confirmation_sign ( 440 TALER_ExchangeSignCallback scb, 441 const struct TALER_HashBlindedPlanchetsP *h_planchets, 442 struct TALER_ExchangePublicKeyP *pub, 443 struct TALER_ExchangeSignatureP *sig) 444 { 445 446 struct TALER_WithdrawConfirmationPS confirm = { 447 .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WITHDRAW), 448 .purpose.size = htonl (sizeof (confirm)), 449 .h_planchets = *h_planchets, 450 .noreveal_index = htonl (0xFFFFFFFF) 451 }; 452 453 return scb (&confirm.purpose, 454 pub, 455 sig); 456 } 457 458 459 enum GNUNET_GenericReturnValue 460 TALER_exchange_online_withdraw_age_confirmation_verify ( 461 const struct TALER_HashBlindedPlanchetsP *h_planchets, 462 uint32_t noreveal_index, 463 const struct TALER_ExchangePublicKeyP *exchange_pub, 464 const struct TALER_ExchangeSignatureP *exchange_sig) 465 { 466 struct TALER_WithdrawConfirmationPS confirm = { 467 .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WITHDRAW), 468 .purpose.size = htonl (sizeof (confirm)), 469 .h_planchets = *h_planchets, 470 .noreveal_index = htonl (noreveal_index) 471 }; 472 473 if (GNUNET_OK != 474 GNUNET_CRYPTO_eddsa_verify ( 475 TALER_SIGNATURE_EXCHANGE_CONFIRM_WITHDRAW, 476 &confirm, 477 &exchange_sig->eddsa_signature, 478 &exchange_pub->eddsa_pub)) 479 { 480 GNUNET_break_op (0); 481 return GNUNET_SYSERR; 482 } 483 return GNUNET_OK; 484 } 485 486 487 enum GNUNET_GenericReturnValue 488 TALER_exchange_online_withdraw_confirmation_verify ( 489 const struct TALER_HashBlindedPlanchetsP *h_planchets, 490 const struct TALER_ExchangePublicKeyP *exchange_pub, 491 const struct TALER_ExchangeSignatureP *exchange_sig) 492 { 493 struct TALER_WithdrawConfirmationPS confirm = { 494 .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WITHDRAW), 495 .purpose.size = htonl (sizeof (confirm)), 496 .h_planchets = *h_planchets, 497 .noreveal_index = htonl (0xFFFFFFFF) 498 }; 499 500 if (GNUNET_OK != 501 GNUNET_CRYPTO_eddsa_verify ( 502 TALER_SIGNATURE_EXCHANGE_CONFIRM_WITHDRAW, 503 &confirm, 504 &exchange_sig->eddsa_signature, 505 &exchange_pub->eddsa_pub)) 506 { 507 GNUNET_break_op (0); 508 return GNUNET_SYSERR; 509 } 510 return GNUNET_OK; 511 } 512 513 514 GNUNET_NETWORK_STRUCT_BEGIN 515 516 /** 517 * @brief Signature made by the exchange over the full set of keys, used 518 * to detect cheating exchanges that give out different sets to 519 * different users. 520 */ 521 struct TALER_ExchangeKeySetPS 522 { 523 524 /** 525 * Purpose is #TALER_SIGNATURE_EXCHANGE_KEY_SET. Signed 526 * by a `struct TALER_ExchangePublicKeyP` using EdDSA. 527 */ 528 struct GNUNET_CRYPTO_SignaturePurpose purpose; 529 530 /** 531 * Time of the key set issue. 532 */ 533 struct GNUNET_TIME_TimestampNBO list_issue_date; 534 535 /** 536 * Hash over the various denomination signing keys returned. 537 */ 538 struct GNUNET_HashCode hc GNUNET_PACKED; 539 }; 540 541 GNUNET_NETWORK_STRUCT_END 542 543 544 enum TALER_ErrorCode 545 TALER_exchange_online_key_set_sign ( 546 TALER_ExchangeSignCallback2 scb, 547 void *cls, 548 struct GNUNET_TIME_Timestamp timestamp, 549 const struct GNUNET_HashCode *hc, 550 struct TALER_ExchangePublicKeyP *pub, 551 struct TALER_ExchangeSignatureP *sig) 552 { 553 struct TALER_ExchangeKeySetPS ks = { 554 .purpose.size = htonl (sizeof (ks)), 555 .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_KEY_SET), 556 .list_issue_date = GNUNET_TIME_timestamp_hton (timestamp), 557 .hc = *hc 558 }; 559 560 return scb (cls, 561 &ks.purpose, 562 pub, 563 sig); 564 } 565 566 567 enum GNUNET_GenericReturnValue 568 TALER_exchange_online_key_set_verify ( 569 struct GNUNET_TIME_Timestamp timestamp, 570 const struct GNUNET_HashCode *hc, 571 const struct TALER_ExchangePublicKeyP *pub, 572 const struct TALER_ExchangeSignatureP *sig) 573 { 574 struct TALER_ExchangeKeySetPS ks = { 575 .purpose.size = htonl (sizeof (ks)), 576 .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_KEY_SET), 577 .list_issue_date = GNUNET_TIME_timestamp_hton (timestamp), 578 .hc = *hc 579 }; 580 581 return 582 GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_KEY_SET, 583 &ks, 584 &sig->eddsa_signature, 585 &pub->eddsa_pub); 586 } 587 588 589 GNUNET_NETWORK_STRUCT_BEGIN 590 591 /** 592 * @brief Format internally used for packing the detailed information 593 * to generate the signature for /track/transfer signatures. 594 */ 595 struct TALER_WireDepositDetailP 596 { 597 598 /** 599 * Hash of the contract 600 */ 601 struct TALER_PrivateContractHashP h_contract_terms; 602 603 /** 604 * Time when the wire transfer was performed by the exchange. 605 */ 606 struct GNUNET_TIME_TimestampNBO execution_time; 607 608 /** 609 * Coin's public key. 610 */ 611 struct TALER_CoinSpendPublicKeyP coin_pub; 612 613 /** 614 * Total value of the coin. 615 */ 616 struct TALER_AmountNBO deposit_value; 617 618 /** 619 * Fees charged by the exchange for the deposit. 620 */ 621 struct TALER_AmountNBO deposit_fee; 622 623 }; 624 625 GNUNET_NETWORK_STRUCT_END 626 627 628 void 629 TALER_exchange_online_wire_deposit_append ( 630 struct GNUNET_HashContext *hash_context, 631 const struct TALER_PrivateContractHashP *h_contract_terms, 632 struct GNUNET_TIME_Timestamp execution_time, 633 const struct TALER_CoinSpendPublicKeyP *coin_pub, 634 const struct TALER_Amount *deposit_value, 635 const struct TALER_Amount *deposit_fee) 636 { 637 struct TALER_WireDepositDetailP dd = { 638 .h_contract_terms = *h_contract_terms, 639 .execution_time = GNUNET_TIME_timestamp_hton (execution_time), 640 .coin_pub = *coin_pub 641 }; 642 TALER_amount_hton (&dd.deposit_value, 643 deposit_value); 644 TALER_amount_hton (&dd.deposit_fee, 645 deposit_fee); 646 GNUNET_CRYPTO_hash_context_read (hash_context, 647 &dd, 648 sizeof (dd)); 649 } 650 651 652 GNUNET_NETWORK_STRUCT_BEGIN 653 654 /** 655 * @brief Format used to generate the signature for /wire/deposit 656 * replies. 657 */ 658 struct TALER_WireDepositDataPS 659 { 660 /** 661 * Purpose header for the signature over the contract with 662 * purpose #TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT. 663 */ 664 struct GNUNET_CRYPTO_SignaturePurpose purpose; 665 666 /** 667 * Total amount that was transferred. 668 */ 669 struct TALER_AmountNBO total; 670 671 /** 672 * Wire fee that was charged. 673 */ 674 struct TALER_AmountNBO wire_fee; 675 676 /** 677 * Public key of the merchant (for all aggregated transactions). 678 */ 679 struct TALER_MerchantPublicKeyP merchant_pub; 680 681 /** 682 * Hash of bank account of the merchant. 683 */ 684 struct TALER_FullPaytoHashP h_payto; 685 686 /** 687 * Hash of the individual deposits that were aggregated, 688 * each in the format of a `struct TALER_WireDepositDetailP`. 689 */ 690 struct GNUNET_HashCode h_details; 691 692 }; 693 694 GNUNET_NETWORK_STRUCT_END 695 696 697 enum TALER_ErrorCode 698 TALER_exchange_online_wire_deposit_sign ( 699 TALER_ExchangeSignCallback scb, 700 const struct TALER_Amount *total, 701 const struct TALER_Amount *wire_fee, 702 const struct TALER_MerchantPublicKeyP *merchant_pub, 703 const struct TALER_FullPayto payto, 704 const struct GNUNET_HashCode *h_details, 705 struct TALER_ExchangePublicKeyP *pub, 706 struct TALER_ExchangeSignatureP *sig) 707 { 708 struct TALER_WireDepositDataPS wdp = { 709 .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT), 710 .purpose.size = htonl (sizeof (wdp)), 711 .merchant_pub = *merchant_pub, 712 .h_details = *h_details 713 }; 714 715 TALER_amount_hton (&wdp.total, 716 total); 717 TALER_amount_hton (&wdp.wire_fee, 718 wire_fee); 719 TALER_full_payto_hash (payto, 720 &wdp.h_payto); 721 return scb (&wdp.purpose, 722 pub, 723 sig); 724 } 725 726 727 enum GNUNET_GenericReturnValue 728 TALER_exchange_online_wire_deposit_verify ( 729 const struct TALER_Amount *total, 730 const struct TALER_Amount *wire_fee, 731 const struct TALER_MerchantPublicKeyP *merchant_pub, 732 const struct TALER_FullPaytoHashP *h_payto, 733 const struct GNUNET_HashCode *h_details, 734 const struct TALER_ExchangePublicKeyP *pub, 735 const struct TALER_ExchangeSignatureP *sig) 736 { 737 struct TALER_WireDepositDataPS wdp = { 738 .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT), 739 .purpose.size = htonl (sizeof (wdp)), 740 .merchant_pub = *merchant_pub, 741 .h_details = *h_details, 742 .h_payto = *h_payto 743 }; 744 745 TALER_amount_hton (&wdp.total, 746 total); 747 TALER_amount_hton (&wdp.wire_fee, 748 wire_fee); 749 return GNUNET_CRYPTO_eddsa_verify ( 750 TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT, 751 &wdp, 752 &sig->eddsa_signature, 753 &pub->eddsa_pub); 754 } 755 756 757 GNUNET_NETWORK_STRUCT_BEGIN 758 759 /** 760 * Details affirmed by the exchange about a wire transfer the exchange 761 * claims to have done with respect to a deposit operation. 762 */ 763 struct TALER_ConfirmWirePS 764 { 765 /** 766 * Purpose header for the signature over the contract with 767 * purpose #TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE. 768 */ 769 struct GNUNET_CRYPTO_SignaturePurpose purpose; 770 771 /** 772 * Hash over the wiring information of the merchant. 773 */ 774 struct TALER_MerchantWireHashP h_wire GNUNET_PACKED; 775 776 /** 777 * Hash over the contract for which this deposit is made. 778 */ 779 struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED; 780 781 /** 782 * Raw value (binary encoding) of the wire transfer subject. 783 */ 784 struct TALER_WireTransferIdentifierRawP wtid; 785 786 /** 787 * The coin's public key. This is the value that must have been 788 * signed (blindly) by the Exchange. 789 */ 790 struct TALER_CoinSpendPublicKeyP coin_pub; 791 792 /** 793 * When did the exchange execute this transfer? Note that the 794 * timestamp may not be exactly the same on the wire, i.e. 795 * because the wire has a different timezone or resolution. 796 */ 797 struct GNUNET_TIME_TimestampNBO execution_time; 798 799 /** 800 * The contribution of @e coin_pub to the total transfer volume. 801 * This is the value of the deposit minus the fee. 802 */ 803 struct TALER_AmountNBO coin_contribution; 804 805 }; 806 807 GNUNET_NETWORK_STRUCT_END 808 809 810 enum TALER_ErrorCode 811 TALER_exchange_online_confirm_wire_sign ( 812 TALER_ExchangeSignCallback scb, 813 const struct TALER_MerchantWireHashP *h_wire, 814 const struct TALER_PrivateContractHashP *h_contract_terms, 815 const struct TALER_WireTransferIdentifierRawP *wtid, 816 const struct TALER_CoinSpendPublicKeyP *coin_pub, 817 struct GNUNET_TIME_Timestamp execution_time, 818 const struct TALER_Amount *coin_contribution, 819 struct TALER_ExchangePublicKeyP *pub, 820 struct TALER_ExchangeSignatureP *sig) 821 822 { 823 struct TALER_ConfirmWirePS cw = { 824 .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE), 825 .purpose.size = htonl (sizeof (cw)), 826 .h_wire = *h_wire, 827 .h_contract_terms = *h_contract_terms, 828 .wtid = *wtid, 829 .coin_pub = *coin_pub, 830 .execution_time = GNUNET_TIME_timestamp_hton (execution_time) 831 }; 832 833 TALER_amount_hton (&cw.coin_contribution, 834 coin_contribution); 835 return scb (&cw.purpose, 836 pub, 837 sig); 838 } 839 840 841 enum GNUNET_GenericReturnValue 842 TALER_exchange_online_confirm_wire_verify ( 843 const struct TALER_MerchantWireHashP *h_wire, 844 const struct TALER_PrivateContractHashP *h_contract_terms, 845 const struct TALER_WireTransferIdentifierRawP *wtid, 846 const struct TALER_CoinSpendPublicKeyP *coin_pub, 847 struct GNUNET_TIME_Timestamp execution_time, 848 const struct TALER_Amount *coin_contribution, 849 const struct TALER_ExchangePublicKeyP *pub, 850 const struct TALER_ExchangeSignatureP *sig) 851 { 852 struct TALER_ConfirmWirePS cw = { 853 .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE), 854 .purpose.size = htonl (sizeof (cw)), 855 .h_wire = *h_wire, 856 .h_contract_terms = *h_contract_terms, 857 .wtid = *wtid, 858 .coin_pub = *coin_pub, 859 .execution_time = GNUNET_TIME_timestamp_hton (execution_time) 860 }; 861 862 TALER_amount_hton (&cw.coin_contribution, 863 coin_contribution); 864 return 865 GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE, 866 &cw, 867 &sig->eddsa_signature, 868 &pub->eddsa_pub); 869 } 870 871 872 GNUNET_NETWORK_STRUCT_BEGIN 873 874 /** 875 * Response by which the exchange affirms that it will 876 * refund a coin as part of the emergency /recoup 877 * protocol. The recoup will go back to the bank 878 * account that created the reserve. 879 */ 880 struct TALER_RecoupConfirmationPS 881 { 882 883 /** 884 * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP 885 */ 886 struct GNUNET_CRYPTO_SignaturePurpose purpose; 887 888 /** 889 * When did the exchange receive the recoup request? 890 * Indirectly determines when the wire transfer is (likely) 891 * to happen. 892 */ 893 struct GNUNET_TIME_TimestampNBO timestamp; 894 895 /** 896 * How much of the coin's value will the exchange transfer? 897 * (Needed in case the coin was partially spent.) 898 */ 899 struct TALER_AmountNBO recoup_amount; 900 901 /** 902 * Public key of the coin. 903 */ 904 struct TALER_CoinSpendPublicKeyP coin_pub; 905 906 /** 907 * Public key of the reserve that will receive the recoup. 908 */ 909 struct TALER_ReservePublicKeyP reserve_pub; 910 }; 911 912 GNUNET_NETWORK_STRUCT_END 913 914 915 enum TALER_ErrorCode 916 TALER_exchange_online_confirm_recoup_sign ( 917 TALER_ExchangeSignCallback scb, 918 struct GNUNET_TIME_Timestamp timestamp, 919 const struct TALER_Amount *recoup_amount, 920 const struct TALER_CoinSpendPublicKeyP *coin_pub, 921 const struct TALER_ReservePublicKeyP *reserve_pub, 922 struct TALER_ExchangePublicKeyP *pub, 923 struct TALER_ExchangeSignatureP *sig) 924 { 925 struct TALER_RecoupConfirmationPS pc = { 926 .purpose.size = htonl (sizeof (pc)), 927 .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP), 928 .timestamp = GNUNET_TIME_timestamp_hton (timestamp), 929 .coin_pub = *coin_pub, 930 .reserve_pub = *reserve_pub 931 }; 932 933 TALER_amount_hton (&pc.recoup_amount, 934 recoup_amount); 935 return scb (&pc.purpose, 936 pub, 937 sig); 938 } 939 940 941 enum GNUNET_GenericReturnValue 942 TALER_exchange_online_confirm_recoup_verify ( 943 struct GNUNET_TIME_Timestamp timestamp, 944 const struct TALER_Amount *recoup_amount, 945 const struct TALER_CoinSpendPublicKeyP *coin_pub, 946 const struct TALER_ReservePublicKeyP *reserve_pub, 947 const struct TALER_ExchangePublicKeyP *pub, 948 const struct TALER_ExchangeSignatureP *sig) 949 { 950 struct TALER_RecoupConfirmationPS pc = { 951 .purpose.size = htonl (sizeof (pc)), 952 .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP), 953 .timestamp = GNUNET_TIME_timestamp_hton (timestamp), 954 .coin_pub = *coin_pub, 955 .reserve_pub = *reserve_pub 956 }; 957 958 TALER_amount_hton (&pc.recoup_amount, 959 recoup_amount); 960 return 961 GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP, 962 &pc, 963 &sig->eddsa_signature, 964 &pub->eddsa_pub); 965 } 966 967 968 GNUNET_NETWORK_STRUCT_BEGIN 969 970 /** 971 * Response by which the exchange affirms that it will refund a refreshed coin 972 * as part of the emergency /recoup protocol. The recoup will go back to the 973 * old coin's balance. 974 */ 975 struct TALER_RecoupRefreshConfirmationPS 976 { 977 978 /** 979 * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH 980 */ 981 struct GNUNET_CRYPTO_SignaturePurpose purpose; 982 983 /** 984 * When did the exchange receive the recoup request? 985 * Indirectly determines when the wire transfer is (likely) 986 * to happen. 987 */ 988 struct GNUNET_TIME_TimestampNBO timestamp; 989 990 /** 991 * How much of the coin's value will the exchange transfer? 992 * (Needed in case the coin was partially spent.) 993 */ 994 struct TALER_AmountNBO recoup_amount; 995 996 /** 997 * Public key of the refreshed coin. 998 */ 999 struct TALER_CoinSpendPublicKeyP coin_pub; 1000 1001 /** 1002 * Public key of the old coin that will receive the recoup. 1003 */ 1004 struct TALER_CoinSpendPublicKeyP old_coin_pub; 1005 }; 1006 1007 GNUNET_NETWORK_STRUCT_END 1008 1009 1010 enum TALER_ErrorCode 1011 TALER_exchange_online_confirm_recoup_refresh_sign ( 1012 TALER_ExchangeSignCallback scb, 1013 struct GNUNET_TIME_Timestamp timestamp, 1014 const struct TALER_Amount *recoup_amount, 1015 const struct TALER_CoinSpendPublicKeyP *coin_pub, 1016 const struct TALER_CoinSpendPublicKeyP *old_coin_pub, 1017 struct TALER_ExchangePublicKeyP *pub, 1018 struct TALER_ExchangeSignatureP *sig) 1019 { 1020 struct TALER_RecoupRefreshConfirmationPS pc = { 1021 .purpose.purpose = htonl ( 1022 TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH), 1023 .purpose.size = htonl (sizeof (pc)), 1024 .timestamp = GNUNET_TIME_timestamp_hton (timestamp), 1025 .coin_pub = *coin_pub, 1026 .old_coin_pub = *old_coin_pub 1027 }; 1028 1029 TALER_amount_hton (&pc.recoup_amount, 1030 recoup_amount); 1031 return scb (&pc.purpose, 1032 pub, 1033 sig); 1034 } 1035 1036 1037 enum GNUNET_GenericReturnValue 1038 TALER_exchange_online_confirm_recoup_refresh_verify ( 1039 struct GNUNET_TIME_Timestamp timestamp, 1040 const struct TALER_Amount *recoup_amount, 1041 const struct TALER_CoinSpendPublicKeyP *coin_pub, 1042 const struct TALER_CoinSpendPublicKeyP *old_coin_pub, 1043 const struct TALER_ExchangePublicKeyP *pub, 1044 const struct TALER_ExchangeSignatureP *sig) 1045 { 1046 struct TALER_RecoupRefreshConfirmationPS pc = { 1047 .purpose.purpose = htonl ( 1048 TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH), 1049 .purpose.size = htonl (sizeof (pc)), 1050 .timestamp = GNUNET_TIME_timestamp_hton (timestamp), 1051 .coin_pub = *coin_pub, 1052 .old_coin_pub = *old_coin_pub 1053 }; 1054 1055 TALER_amount_hton (&pc.recoup_amount, 1056 recoup_amount); 1057 1058 return 1059 GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH, 1060 &pc, 1061 &sig->eddsa_signature, 1062 &pub->eddsa_pub); 1063 } 1064 1065 1066 GNUNET_NETWORK_STRUCT_BEGIN 1067 1068 /** 1069 * Response by which the exchange affirms that it does not 1070 * currently know a denomination by the given hash. 1071 */ 1072 struct TALER_DenominationUnknownAffirmationPS 1073 { 1074 1075 /** 1076 * Purpose is #TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN 1077 */ 1078 struct GNUNET_CRYPTO_SignaturePurpose purpose; 1079 1080 /** 1081 * When did the exchange sign this message. 1082 */ 1083 struct GNUNET_TIME_TimestampNBO timestamp; 1084 1085 /** 1086 * Hash of the public denomination key we do not know. 1087 */ 1088 struct TALER_DenominationHashP h_denom_pub; 1089 }; 1090 1091 GNUNET_NETWORK_STRUCT_END 1092 1093 1094 enum TALER_ErrorCode 1095 TALER_exchange_online_denomination_unknown_sign ( 1096 TALER_ExchangeSignCallback scb, 1097 struct GNUNET_TIME_Timestamp timestamp, 1098 const struct TALER_DenominationHashP *h_denom_pub, 1099 struct TALER_ExchangePublicKeyP *pub, 1100 struct TALER_ExchangeSignatureP *sig) 1101 { 1102 struct TALER_DenominationUnknownAffirmationPS dua = { 1103 .purpose.size = htonl (sizeof (dua)), 1104 .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN), 1105 .timestamp = GNUNET_TIME_timestamp_hton (timestamp), 1106 .h_denom_pub = *h_denom_pub, 1107 }; 1108 1109 return scb (&dua.purpose, 1110 pub, 1111 sig); 1112 } 1113 1114 1115 enum GNUNET_GenericReturnValue 1116 TALER_exchange_online_denomination_unknown_verify ( 1117 struct GNUNET_TIME_Timestamp timestamp, 1118 const struct TALER_DenominationHashP *h_denom_pub, 1119 const struct TALER_ExchangePublicKeyP *pub, 1120 const struct TALER_ExchangeSignatureP *sig) 1121 { 1122 struct TALER_DenominationUnknownAffirmationPS dua = { 1123 .purpose.size = htonl (sizeof (dua)), 1124 .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN), 1125 .timestamp = GNUNET_TIME_timestamp_hton (timestamp), 1126 .h_denom_pub = *h_denom_pub, 1127 }; 1128 1129 return 1130 GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN, 1131 &dua, 1132 &sig->eddsa_signature, 1133 &pub->eddsa_pub); 1134 } 1135 1136 1137 GNUNET_NETWORK_STRUCT_BEGIN 1138 1139 /** 1140 * Response by which the exchange affirms that it does not 1141 * currently consider the given denomination to be valid 1142 * for the requested operation. 1143 */ 1144 struct TALER_DenominationExpiredAffirmationPS 1145 { 1146 1147 /** 1148 * Purpose is #TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED 1149 */ 1150 struct GNUNET_CRYPTO_SignaturePurpose purpose; 1151 1152 /** 1153 * When did the exchange sign this message. 1154 */ 1155 struct GNUNET_TIME_TimestampNBO timestamp; 1156 1157 /** 1158 * Name of the operation that is not allowed at this time. Might NOT be 0-terminated, but is padded with 0s. 1159 */ 1160 char operation[8]; 1161 1162 /** 1163 * Hash of the public denomination key we do not know. 1164 */ 1165 struct TALER_DenominationHashP h_denom_pub; 1166 1167 }; 1168 1169 GNUNET_NETWORK_STRUCT_END 1170 1171 1172 enum TALER_ErrorCode 1173 TALER_exchange_online_denomination_expired_sign ( 1174 TALER_ExchangeSignCallback scb, 1175 struct GNUNET_TIME_Timestamp timestamp, 1176 const struct TALER_DenominationHashP *h_denom_pub, 1177 const char *op, 1178 struct TALER_ExchangePublicKeyP *pub, 1179 struct TALER_ExchangeSignatureP *sig) 1180 { 1181 struct TALER_DenominationExpiredAffirmationPS dua = { 1182 .purpose.size = htonl (sizeof (dua)), 1183 .purpose.purpose = htonl ( 1184 TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED), 1185 .timestamp = GNUNET_TIME_timestamp_hton (timestamp), 1186 .h_denom_pub = *h_denom_pub, 1187 }; 1188 1189 /* strncpy would create a compiler warning */ 1190 GNUNET_memcpy (dua.operation, 1191 op, 1192 GNUNET_MIN (sizeof (dua.operation), 1193 strlen (op))); 1194 return scb (&dua.purpose, 1195 pub, 1196 sig); 1197 } 1198 1199 1200 enum GNUNET_GenericReturnValue 1201 TALER_exchange_online_denomination_expired_verify ( 1202 struct GNUNET_TIME_Timestamp timestamp, 1203 const struct TALER_DenominationHashP *h_denom_pub, 1204 const char *op, 1205 const struct TALER_ExchangePublicKeyP *pub, 1206 const struct TALER_ExchangeSignatureP *sig) 1207 { 1208 struct TALER_DenominationExpiredAffirmationPS dua = { 1209 .purpose.size = htonl (sizeof (dua)), 1210 .purpose.purpose = htonl ( 1211 TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED), 1212 .timestamp = GNUNET_TIME_timestamp_hton (timestamp), 1213 .h_denom_pub = *h_denom_pub, 1214 }; 1215 1216 /* strncpy would create a compiler warning */ 1217 GNUNET_memcpy (dua.operation, 1218 op, 1219 GNUNET_MIN (sizeof (dua.operation), 1220 strlen (op))); 1221 return 1222 GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED, 1223 &dua, 1224 &sig->eddsa_signature, 1225 &pub->eddsa_pub); 1226 } 1227 1228 1229 GNUNET_NETWORK_STRUCT_BEGIN 1230 1231 /** 1232 * Response by which the exchange affirms that it has 1233 * closed a reserve and send back the funds. 1234 */ 1235 struct TALER_ReserveCloseConfirmationPS 1236 { 1237 1238 /** 1239 * Purpose is #TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED 1240 */ 1241 struct GNUNET_CRYPTO_SignaturePurpose purpose; 1242 1243 /** 1244 * When did the exchange initiate the wire transfer. 1245 */ 1246 struct GNUNET_TIME_TimestampNBO timestamp; 1247 1248 /** 1249 * How much did the exchange send? 1250 */ 1251 struct TALER_AmountNBO closing_amount; 1252 1253 /** 1254 * How much did the exchange charge for closing the reserve? 1255 */ 1256 struct TALER_AmountNBO closing_fee; 1257 1258 /** 1259 * Public key of the reserve that was closed. 1260 */ 1261 struct TALER_ReservePublicKeyP reserve_pub; 1262 1263 /** 1264 * Hash of the receiver's bank account. 1265 */ 1266 struct TALER_FullPaytoHashP h_payto; 1267 1268 /** 1269 * Wire transfer subject. 1270 */ 1271 struct TALER_WireTransferIdentifierRawP wtid; 1272 }; 1273 1274 GNUNET_NETWORK_STRUCT_END 1275 1276 1277 enum TALER_ErrorCode 1278 TALER_exchange_online_reserve_closed_sign ( 1279 TALER_ExchangeSignCallback scb, 1280 struct GNUNET_TIME_Timestamp timestamp, 1281 const struct TALER_Amount *closing_amount, 1282 const struct TALER_Amount *closing_fee, 1283 const struct TALER_FullPayto payto, 1284 const struct TALER_WireTransferIdentifierRawP *wtid, 1285 const struct TALER_ReservePublicKeyP *reserve_pub, 1286 struct TALER_ExchangePublicKeyP *pub, 1287 struct TALER_ExchangeSignatureP *sig) 1288 { 1289 struct TALER_ReserveCloseConfirmationPS rcc = { 1290 .purpose.size = htonl (sizeof (rcc)), 1291 .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED), 1292 .wtid = *wtid, 1293 .reserve_pub = *reserve_pub, 1294 .timestamp = GNUNET_TIME_timestamp_hton (timestamp) 1295 }; 1296 1297 TALER_amount_hton (&rcc.closing_amount, 1298 closing_amount); 1299 TALER_amount_hton (&rcc.closing_fee, 1300 closing_fee); 1301 TALER_full_payto_hash (payto, 1302 &rcc.h_payto); 1303 return scb (&rcc.purpose, 1304 pub, 1305 sig); 1306 } 1307 1308 1309 enum GNUNET_GenericReturnValue 1310 TALER_exchange_online_reserve_closed_verify ( 1311 struct GNUNET_TIME_Timestamp timestamp, 1312 const struct TALER_Amount *closing_amount, 1313 const struct TALER_Amount *closing_fee, 1314 const struct TALER_FullPayto payto, 1315 const struct TALER_WireTransferIdentifierRawP *wtid, 1316 const struct TALER_ReservePublicKeyP *reserve_pub, 1317 const struct TALER_ExchangePublicKeyP *pub, 1318 const struct TALER_ExchangeSignatureP *sig) 1319 { 1320 struct TALER_ReserveCloseConfirmationPS rcc = { 1321 .purpose.size = htonl (sizeof (rcc)), 1322 .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED), 1323 .wtid = *wtid, 1324 .reserve_pub = *reserve_pub, 1325 .timestamp = GNUNET_TIME_timestamp_hton (timestamp) 1326 }; 1327 1328 TALER_amount_hton (&rcc.closing_amount, 1329 closing_amount); 1330 TALER_amount_hton (&rcc.closing_fee, 1331 closing_fee); 1332 TALER_full_payto_hash (payto, 1333 &rcc.h_payto); 1334 return GNUNET_CRYPTO_eddsa_verify ( 1335 TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED, 1336 &rcc, 1337 &sig->eddsa_signature, 1338 &pub->eddsa_pub); 1339 } 1340 1341 1342 GNUNET_NETWORK_STRUCT_BEGIN 1343 1344 /** 1345 * Response by which the exchange affirms that it has 1346 * received funds deposited into a purse. 1347 */ 1348 struct TALER_PurseCreateDepositConfirmationPS 1349 { 1350 1351 /** 1352 * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_CREATION 1353 */ 1354 struct GNUNET_CRYPTO_SignaturePurpose purpose; 1355 1356 /** 1357 * When did the exchange receive the deposits. 1358 */ 1359 struct GNUNET_TIME_TimestampNBO exchange_time; 1360 1361 /** 1362 * When will the purse expire? 1363 */ 1364 struct GNUNET_TIME_TimestampNBO purse_expiration; 1365 1366 /** 1367 * How much should the purse ultimately contain. 1368 */ 1369 struct TALER_AmountNBO amount_without_fee; 1370 1371 /** 1372 * How much was deposited so far. 1373 */ 1374 struct TALER_AmountNBO total_deposited; 1375 1376 /** 1377 * Public key of the purse. 1378 */ 1379 struct TALER_PurseContractPublicKeyP purse_pub; 1380 1381 /** 1382 * Hash of the contract of the purse. 1383 */ 1384 struct TALER_PrivateContractHashP h_contract_terms; 1385 1386 }; 1387 1388 GNUNET_NETWORK_STRUCT_END 1389 1390 1391 enum TALER_ErrorCode 1392 TALER_exchange_online_purse_created_sign ( 1393 TALER_ExchangeSignCallback scb, 1394 struct GNUNET_TIME_Timestamp exchange_time, 1395 struct GNUNET_TIME_Timestamp purse_expiration, 1396 const struct TALER_Amount *amount_without_fee, 1397 const struct TALER_Amount *total_deposited, 1398 const struct TALER_PurseContractPublicKeyP *purse_pub, 1399 const struct TALER_PrivateContractHashP *h_contract_terms, 1400 struct TALER_ExchangePublicKeyP *pub, 1401 struct TALER_ExchangeSignatureP *sig) 1402 { 1403 struct TALER_PurseCreateDepositConfirmationPS dc = { 1404 .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_CREATION), 1405 .purpose.size = htonl (sizeof (dc)), 1406 .h_contract_terms = *h_contract_terms, 1407 .purse_pub = *purse_pub, 1408 .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration), 1409 .exchange_time = GNUNET_TIME_timestamp_hton (exchange_time) 1410 }; 1411 1412 TALER_amount_hton (&dc.amount_without_fee, 1413 amount_without_fee); 1414 TALER_amount_hton (&dc.total_deposited, 1415 total_deposited); 1416 return scb (&dc.purpose, 1417 pub, 1418 sig); 1419 } 1420 1421 1422 enum GNUNET_GenericReturnValue 1423 TALER_exchange_online_purse_created_verify ( 1424 struct GNUNET_TIME_Timestamp exchange_time, 1425 struct GNUNET_TIME_Timestamp purse_expiration, 1426 const struct TALER_Amount *amount_without_fee, 1427 const struct TALER_Amount *total_deposited, 1428 const struct TALER_PurseContractPublicKeyP *purse_pub, 1429 const struct TALER_PrivateContractHashP *h_contract_terms, 1430 const struct TALER_ExchangePublicKeyP *pub, 1431 const struct TALER_ExchangeSignatureP *sig) 1432 { 1433 struct TALER_PurseCreateDepositConfirmationPS dc = { 1434 .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_CREATION), 1435 .purpose.size = htonl (sizeof (dc)), 1436 .h_contract_terms = *h_contract_terms, 1437 .purse_pub = *purse_pub, 1438 .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration), 1439 .exchange_time = GNUNET_TIME_timestamp_hton (exchange_time) 1440 }; 1441 1442 TALER_amount_hton (&dc.amount_without_fee, 1443 amount_without_fee); 1444 TALER_amount_hton (&dc.total_deposited, 1445 total_deposited); 1446 return GNUNET_CRYPTO_eddsa_verify ( 1447 TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_CREATION, 1448 &dc, 1449 &sig->eddsa_signature, 1450 &pub->eddsa_pub); 1451 } 1452 1453 1454 GNUNET_NETWORK_STRUCT_BEGIN 1455 1456 /** 1457 * Response by which the exchange affirms that it has 1458 * received funds deposited into a purse. 1459 */ 1460 struct TALER_CoinPurseRefundConfirmationPS 1461 { 1462 1463 /** 1464 * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_REFUND 1465 */ 1466 struct GNUNET_CRYPTO_SignaturePurpose purpose; 1467 1468 /** 1469 * Public key of the purse. 1470 */ 1471 struct TALER_PurseContractPublicKeyP purse_pub; 1472 1473 /** 1474 * Public key of the coin. 1475 */ 1476 struct TALER_CoinSpendPublicKeyP coin_pub; 1477 1478 /** 1479 * How much will be refunded to the purse. 1480 */ 1481 struct TALER_AmountNBO refunded_amount; 1482 1483 /** 1484 * How much was the refund fee. 1485 */ 1486 struct TALER_AmountNBO refund_fee; 1487 1488 }; 1489 1490 GNUNET_NETWORK_STRUCT_END 1491 1492 1493 enum TALER_ErrorCode 1494 TALER_exchange_online_purse_refund_sign ( 1495 TALER_ExchangeSignCallback scb, 1496 const struct TALER_Amount *amount_without_fee, 1497 const struct TALER_Amount *refund_fee, 1498 const struct TALER_CoinSpendPublicKeyP *coin_pub, 1499 const struct TALER_PurseContractPublicKeyP *purse_pub, 1500 struct TALER_ExchangePublicKeyP *pub, 1501 struct TALER_ExchangeSignatureP *sig) 1502 { 1503 struct TALER_CoinPurseRefundConfirmationPS dc = { 1504 .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_REFUND), 1505 .purpose.size = htonl (sizeof (dc)), 1506 .coin_pub = *coin_pub, 1507 .purse_pub = *purse_pub, 1508 }; 1509 1510 TALER_amount_hton (&dc.refunded_amount, 1511 amount_without_fee); 1512 TALER_amount_hton (&dc.refund_fee, 1513 refund_fee); 1514 return scb (&dc.purpose, 1515 pub, 1516 sig); 1517 } 1518 1519 1520 enum GNUNET_GenericReturnValue 1521 TALER_exchange_online_purse_refund_verify ( 1522 const struct TALER_Amount *amount_without_fee, 1523 const struct TALER_Amount *refund_fee, 1524 const struct TALER_CoinSpendPublicKeyP *coin_pub, 1525 const struct TALER_PurseContractPublicKeyP *purse_pub, 1526 const struct TALER_ExchangePublicKeyP *pub, 1527 const struct TALER_ExchangeSignatureP *sig) 1528 { 1529 struct TALER_CoinPurseRefundConfirmationPS dc = { 1530 .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_REFUND), 1531 .purpose.size = htonl (sizeof (dc)), 1532 .coin_pub = *coin_pub, 1533 .purse_pub = *purse_pub, 1534 }; 1535 1536 TALER_amount_hton (&dc.refunded_amount, 1537 amount_without_fee); 1538 TALER_amount_hton (&dc.refund_fee, 1539 refund_fee); 1540 return GNUNET_CRYPTO_eddsa_verify ( 1541 TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_REFUND, 1542 &dc, 1543 &sig->eddsa_signature, 1544 &pub->eddsa_pub); 1545 } 1546 1547 1548 GNUNET_NETWORK_STRUCT_BEGIN 1549 1550 /** 1551 * Response by which the exchange affirms that it has 1552 * merged a purse into a reserve. 1553 */ 1554 struct TALER_PurseMergedConfirmationPS 1555 { 1556 1557 /** 1558 * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_MERGED 1559 */ 1560 struct GNUNET_CRYPTO_SignaturePurpose purpose; 1561 1562 /** 1563 * When did the exchange receive the deposits. 1564 */ 1565 struct GNUNET_TIME_TimestampNBO exchange_time; 1566 1567 /** 1568 * When will the purse expire? 1569 */ 1570 struct GNUNET_TIME_TimestampNBO purse_expiration; 1571 1572 /** 1573 * How much should the purse ultimately contain. 1574 */ 1575 struct TALER_AmountNBO amount_without_fee; 1576 1577 /** 1578 * Public key of the purse. 1579 */ 1580 struct TALER_PurseContractPublicKeyP purse_pub; 1581 1582 /** 1583 * Public key of the reserve. 1584 */ 1585 struct TALER_ReservePublicKeyP reserve_pub; 1586 1587 /** 1588 * Hash of the contract of the purse. 1589 */ 1590 struct TALER_PrivateContractHashP h_contract_terms; 1591 1592 /** 1593 * Hash of the provider URL hosting the reserve. 1594 */ 1595 struct GNUNET_HashCode h_provider_url; 1596 1597 }; 1598 1599 GNUNET_NETWORK_STRUCT_END 1600 1601 1602 enum TALER_ErrorCode 1603 TALER_exchange_online_purse_merged_sign ( 1604 TALER_ExchangeSignCallback scb, 1605 struct GNUNET_TIME_Timestamp exchange_time, 1606 struct GNUNET_TIME_Timestamp purse_expiration, 1607 const struct TALER_Amount *amount_without_fee, 1608 const struct TALER_PurseContractPublicKeyP *purse_pub, 1609 const struct TALER_PrivateContractHashP *h_contract_terms, 1610 const struct TALER_ReservePublicKeyP *reserve_pub, 1611 const char *exchange_url, 1612 struct TALER_ExchangePublicKeyP *pub, 1613 struct TALER_ExchangeSignatureP *sig) 1614 { 1615 struct TALER_PurseMergedConfirmationPS dc = { 1616 .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_MERGED), 1617 .purpose.size = htonl (sizeof (dc)), 1618 .h_contract_terms = *h_contract_terms, 1619 .purse_pub = *purse_pub, 1620 .reserve_pub = *reserve_pub, 1621 .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration), 1622 .exchange_time = GNUNET_TIME_timestamp_hton (exchange_time) 1623 }; 1624 1625 TALER_amount_hton (&dc.amount_without_fee, 1626 amount_without_fee); 1627 GNUNET_CRYPTO_hash (exchange_url, 1628 strlen (exchange_url) + 1, 1629 &dc.h_provider_url); 1630 return scb (&dc.purpose, 1631 pub, 1632 sig); 1633 } 1634 1635 1636 enum GNUNET_GenericReturnValue 1637 TALER_exchange_online_purse_merged_verify ( 1638 struct GNUNET_TIME_Timestamp exchange_time, 1639 struct GNUNET_TIME_Timestamp purse_expiration, 1640 const struct TALER_Amount *amount_without_fee, 1641 const struct TALER_PurseContractPublicKeyP *purse_pub, 1642 const struct TALER_PrivateContractHashP *h_contract_terms, 1643 const struct TALER_ReservePublicKeyP *reserve_pub, 1644 const char *exchange_url, 1645 const struct TALER_ExchangePublicKeyP *pub, 1646 const struct TALER_ExchangeSignatureP *sig) 1647 { 1648 struct TALER_PurseMergedConfirmationPS dc = { 1649 .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_MERGED), 1650 .purpose.size = htonl (sizeof (dc)), 1651 .h_contract_terms = *h_contract_terms, 1652 .purse_pub = *purse_pub, 1653 .reserve_pub = *reserve_pub, 1654 .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration), 1655 .exchange_time = GNUNET_TIME_timestamp_hton (exchange_time) 1656 }; 1657 1658 TALER_amount_hton (&dc.amount_without_fee, 1659 amount_without_fee); 1660 GNUNET_CRYPTO_hash (exchange_url, 1661 strlen (exchange_url) + 1, 1662 &dc.h_provider_url); 1663 return 1664 GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_MERGED, 1665 &dc, 1666 &sig->eddsa_signature, 1667 &pub->eddsa_pub); 1668 } 1669 1670 1671 GNUNET_NETWORK_STRUCT_BEGIN 1672 1673 /** 1674 * @brief Format used to generate the signature on a purse status 1675 * from the exchange. 1676 */ 1677 struct TALER_PurseStatusPS 1678 { 1679 /** 1680 * Purpose must be #TALER_SIGNATURE_EXCHANGE_PURSE_STATUS. Signed 1681 * by a `struct TALER_ExchangePublicKeyP` using EdDSA. 1682 */ 1683 struct GNUNET_CRYPTO_SignaturePurpose purpose; 1684 1685 /** 1686 * Time when the purse was merged, possibly 'never'. 1687 */ 1688 struct GNUNET_TIME_TimestampNBO merge_timestamp; 1689 1690 /** 1691 * Time when the purse was deposited last, possibly 'never'. 1692 */ 1693 struct GNUNET_TIME_TimestampNBO deposit_timestamp; 1694 1695 /** 1696 * Amount deposited in total in the purse without fees. 1697 * May be possibly less than the target amount. 1698 */ 1699 struct TALER_AmountNBO balance; 1700 1701 }; 1702 1703 GNUNET_NETWORK_STRUCT_END 1704 1705 1706 enum TALER_ErrorCode 1707 TALER_exchange_online_purse_status_sign ( 1708 TALER_ExchangeSignCallback scb, 1709 struct GNUNET_TIME_Timestamp merge_timestamp, 1710 struct GNUNET_TIME_Timestamp deposit_timestamp, 1711 const struct TALER_Amount *balance, 1712 struct TALER_ExchangePublicKeyP *pub, 1713 struct TALER_ExchangeSignatureP *sig) 1714 { 1715 struct TALER_PurseStatusPS dcs = { 1716 .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_PURSE_STATUS), 1717 .purpose.size = htonl (sizeof (dcs)), 1718 .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp), 1719 .deposit_timestamp = GNUNET_TIME_timestamp_hton (deposit_timestamp) 1720 }; 1721 1722 TALER_amount_hton (&dcs.balance, 1723 balance); 1724 return scb (&dcs.purpose, 1725 pub, 1726 sig); 1727 } 1728 1729 1730 enum GNUNET_GenericReturnValue 1731 TALER_exchange_online_purse_status_verify ( 1732 struct GNUNET_TIME_Timestamp merge_timestamp, 1733 struct GNUNET_TIME_Timestamp deposit_timestamp, 1734 const struct TALER_Amount *balance, 1735 const struct TALER_ExchangePublicKeyP *exchange_pub, 1736 const struct TALER_ExchangeSignatureP *exchange_sig) 1737 { 1738 struct TALER_PurseStatusPS dcs = { 1739 .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_PURSE_STATUS), 1740 .purpose.size = htonl (sizeof (dcs)), 1741 .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp), 1742 .deposit_timestamp = GNUNET_TIME_timestamp_hton (deposit_timestamp) 1743 }; 1744 1745 TALER_amount_hton (&dcs.balance, 1746 balance); 1747 if (GNUNET_OK != 1748 GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_PURSE_STATUS, 1749 &dcs, 1750 &exchange_sig->eddsa_signature, 1751 &exchange_pub->eddsa_pub)) 1752 { 1753 GNUNET_break_op (0); 1754 return GNUNET_SYSERR; 1755 } 1756 return GNUNET_OK; 1757 } 1758 1759 1760 GNUNET_NETWORK_STRUCT_BEGIN 1761 1762 /** 1763 * Message signed by the exchange to affirm that the 1764 * owner of a reserve has certain attributes. 1765 */ 1766 struct TALER_ExchangeAttestPS 1767 { 1768 1769 /** 1770 * Purpose is #TALER_SIGNATURE_EXCHANGE_RESERVE_ATTEST_DETAILS 1771 */ 1772 struct GNUNET_CRYPTO_SignaturePurpose purpose; 1773 1774 /** 1775 * Time when the attestation was made. 1776 */ 1777 struct GNUNET_TIME_TimestampNBO attest_timestamp; 1778 1779 /** 1780 * Time when the attestation expires. 1781 */ 1782 struct GNUNET_TIME_TimestampNBO expiration_time; 1783 1784 /** 1785 * Public key of the reserve for which the attributes 1786 * are attested. 1787 */ 1788 struct TALER_ReservePublicKeyP reserve_pub; 1789 1790 /** 1791 * Hash over the attributes. 1792 */ 1793 struct GNUNET_HashCode h_attributes; 1794 1795 }; 1796 1797 GNUNET_NETWORK_STRUCT_END 1798 1799 1800 enum TALER_ErrorCode 1801 TALER_exchange_online_reserve_attest_details_sign ( 1802 TALER_ExchangeSignCallback scb, 1803 struct GNUNET_TIME_Timestamp attest_timestamp, 1804 struct GNUNET_TIME_Timestamp expiration_time, 1805 const struct TALER_ReservePublicKeyP *reserve_pub, 1806 const json_t *attributes, 1807 struct TALER_ExchangePublicKeyP *pub, 1808 struct TALER_ExchangeSignatureP *sig) 1809 { 1810 struct TALER_ExchangeAttestPS rap = { 1811 .purpose.size = htonl (sizeof (rap)), 1812 .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_ATTEST_DETAILS), 1813 .attest_timestamp = GNUNET_TIME_timestamp_hton (attest_timestamp), 1814 .expiration_time = GNUNET_TIME_timestamp_hton (expiration_time), 1815 .reserve_pub = *reserve_pub 1816 }; 1817 1818 TALER_json_hash (attributes, 1819 &rap.h_attributes); 1820 return scb (&rap.purpose, 1821 pub, 1822 sig); 1823 } 1824 1825 1826 enum GNUNET_GenericReturnValue 1827 TALER_exchange_online_reserve_attest_details_verify ( 1828 struct GNUNET_TIME_Timestamp attest_timestamp, 1829 struct GNUNET_TIME_Timestamp expiration_time, 1830 const struct TALER_ReservePublicKeyP *reserve_pub, 1831 const json_t *attributes, 1832 struct TALER_ExchangePublicKeyP *pub, 1833 struct TALER_ExchangeSignatureP *sig) 1834 { 1835 struct TALER_ExchangeAttestPS rap = { 1836 .purpose.size = htonl (sizeof (rap)), 1837 .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_ATTEST_DETAILS), 1838 .attest_timestamp = GNUNET_TIME_timestamp_hton (attest_timestamp), 1839 .expiration_time = GNUNET_TIME_timestamp_hton (expiration_time), 1840 .reserve_pub = *reserve_pub 1841 }; 1842 1843 TALER_json_hash (attributes, 1844 &rap.h_attributes); 1845 if (GNUNET_OK != 1846 GNUNET_CRYPTO_eddsa_verify ( 1847 TALER_SIGNATURE_EXCHANGE_RESERVE_ATTEST_DETAILS, 1848 &rap, 1849 &sig->eddsa_signature, 1850 &pub->eddsa_pub)) 1851 { 1852 GNUNET_break_op (0); 1853 return GNUNET_SYSERR; 1854 } 1855 return GNUNET_OK; 1856 } 1857 1858 1859 /* end of exchange_signatures.c */