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