LCOV - code coverage report
Current view: top level - util - exchange_signatures.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 63.8 % 312 199
Test Date: 2026-04-14 15:39:31 Functions: 62.2 % 37 23

            Line data    Source code
       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           84 : 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           84 : {
     114          168 :   struct TALER_DepositConfirmationPS dcs = {
     115           84 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT),
     116           84 :     .purpose.size = htonl (sizeof (struct TALER_DepositConfirmationPS)),
     117              :     .h_contract_terms = *h_contract_terms,
     118              :     .h_wire = *h_wire,
     119           84 :     .exchange_timestamp = GNUNET_TIME_timestamp_hton (exchange_timestamp),
     120           84 :     .wire_deadline = GNUNET_TIME_timestamp_hton (wire_deadline),
     121           84 :     .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           84 :   hc = GNUNET_CRYPTO_hash_context_start ();
     128          170 :   for (unsigned int i = 0; i<num_coins; i++)
     129           86 :     GNUNET_CRYPTO_hash_context_read (hc,
     130           86 :                                      coin_sigs[i],
     131              :                                      sizeof (*coin_sigs[i]));
     132           84 :   GNUNET_CRYPTO_hash_context_finish (hc,
     133              :                                      &dcs.h_coin_sigs);
     134           84 :   if (NULL != h_policy)
     135            0 :     dcs.h_policy = *h_policy;
     136           84 :   TALER_amount_hton (&dcs.total_without_fee,
     137              :                      total_without_fee);
     138           84 :   return scb (&dcs.purpose,
     139              :               pub,
     140              :               sig);
     141              : }
     142              : 
     143              : 
     144              : enum GNUNET_GenericReturnValue
     145           88 : 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           88 : {
     159          176 :   struct TALER_DepositConfirmationPS dcs = {
     160           88 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT),
     161           88 :     .purpose.size = htonl (sizeof (struct TALER_DepositConfirmationPS)),
     162              :     .h_contract_terms = *h_contract_terms,
     163              :     .h_wire = *h_wire,
     164           88 :     .exchange_timestamp = GNUNET_TIME_timestamp_hton (exchange_timestamp),
     165           88 :     .wire_deadline = GNUNET_TIME_timestamp_hton (wire_deadline),
     166           88 :     .refund_deadline = GNUNET_TIME_timestamp_hton (refund_deadline),
     167              :     .merchant_pub = *merchant_pub
     168              :   };
     169              :   struct GNUNET_HashContext *hc;
     170              : 
     171           88 :   hc = GNUNET_CRYPTO_hash_context_start ();
     172          178 :   for (unsigned int i = 0; i<num_coins; i++)
     173           90 :     GNUNET_CRYPTO_hash_context_read (hc,
     174           90 :                                      coin_sigs[i],
     175              :                                      sizeof (*coin_sigs[i]));
     176           88 :   GNUNET_CRYPTO_hash_context_finish (hc,
     177              :                                      &dcs.h_coin_sigs);
     178           88 :   if (NULL != h_policy)
     179           88 :     dcs.h_policy = *h_policy;
     180           88 :   TALER_amount_hton (&dcs.total_without_fee,
     181              :                      total_without_fee);
     182           88 :   if (GNUNET_OK !=
     183           88 :       GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT,
     184              :                                   &dcs,
     185              :                                   &exchange_sig->eddsa_signature,
     186              :                                   &exchange_pub->eddsa_pub))
     187              :   {
     188            0 :     GNUNET_break_op (0);
     189            0 :     return GNUNET_SYSERR;
     190              :   }
     191           88 :   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           10 : 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           20 :   struct TALER_RefundConfirmationPS rc = {
     253           10 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND),
     254           10 :     .purpose.size = htonl (sizeof (rc)),
     255              :     .h_contract_terms = *h_contract_terms,
     256              :     .coin_pub = *coin_pub,
     257              :     .merchant = *merchant,
     258           10 :     .rtransaction_id = GNUNET_htonll (rtransaction_id)
     259              :   };
     260              : 
     261           10 :   TALER_amount_hton (&rc.refund_amount,
     262              :                      refund_amount);
     263           10 :   return scb (&rc.purpose,
     264              :               pub,
     265              :               sig);
     266              : }
     267              : 
     268              : 
     269              : enum GNUNET_GenericReturnValue
     270           10 : 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           20 :   struct TALER_RefundConfirmationPS rc = {
     280           10 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND),
     281           10 :     .purpose.size = htonl (sizeof (rc)),
     282              :     .h_contract_terms = *h_contract_terms,
     283              :     .coin_pub = *coin_pub,
     284              :     .merchant = *merchant,
     285           10 :     .rtransaction_id = GNUNET_htonll (rtransaction_id)
     286              :   };
     287              : 
     288           10 :   TALER_amount_hton (&rc.refund_amount,
     289              :                      refund_amount);
     290           10 :   if (GNUNET_OK !=
     291           10 :       GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND,
     292              :                                   &rc,
     293              :                                   &sig->eddsa_signature,
     294              :                                   &pub->eddsa_pub))
     295              :   {
     296            0 :     GNUNET_break_op (0);
     297            0 :     return GNUNET_SYSERR;
     298              :   }
     299           10 :   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           16 : 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           16 :   struct TALER_RefreshMeltConfirmationPS confirm = {
     344           16 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT),
     345           16 :     .purpose.size = htonl (sizeof (confirm)),
     346              :     .rc = *rc,
     347           16 :     .noreveal_index = htonl (noreveal_index)
     348              :   };
     349              : 
     350           16 :   return scb (&confirm.purpose,
     351              :               pub,
     352              :               sig);
     353              : }
     354              : 
     355              : 
     356              : enum GNUNET_GenericReturnValue
     357           16 : 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           16 :   struct TALER_RefreshMeltConfirmationPS confirm = {
     364           16 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT),
     365           16 :     .purpose.size = htonl (sizeof (confirm)),
     366              :     .rc = *rc,
     367           16 :     .noreveal_index = htonl (noreveal_index)
     368              :   };
     369              : 
     370              :   return
     371           16 :     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            3 : 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            3 :   struct TALER_WithdrawConfirmationPS confirm = {
     425            3 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WITHDRAW),
     426            3 :     .purpose.size = htonl (sizeof (confirm)),
     427              :     .h_planchets = *h_planchets,
     428            3 :     .noreveal_index = htonl (noreveal_index)
     429              :   };
     430              : 
     431            3 :   return scb (&confirm.purpose,
     432              :               pub,
     433              :               sig);
     434              : }
     435              : 
     436              : 
     437              : enum TALER_ErrorCode
     438            0 : 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            0 :   struct TALER_WithdrawConfirmationPS confirm = {
     446            0 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WITHDRAW),
     447            0 :     .purpose.size = htonl (sizeof (confirm)),
     448              :     .h_planchets = *h_planchets,
     449            0 :     .noreveal_index = htonl (0xFFFFFFFF)
     450              :   };
     451              : 
     452            0 :   return scb (&confirm.purpose,
     453              :               pub,
     454              :               sig);
     455              : }
     456              : 
     457              : 
     458              : enum GNUNET_GenericReturnValue
     459            3 : 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            3 :   struct TALER_WithdrawConfirmationPS confirm = {
     466            3 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WITHDRAW),
     467            3 :     .purpose.size = htonl (sizeof (confirm)),
     468              :     .h_planchets = *h_planchets,
     469            3 :     .noreveal_index = htonl (noreveal_index)
     470              :   };
     471              : 
     472            3 :   if (GNUNET_OK !=
     473            3 :       GNUNET_CRYPTO_eddsa_verify (
     474              :         TALER_SIGNATURE_EXCHANGE_CONFIRM_WITHDRAW,
     475              :         &confirm,
     476              :         &exchange_sig->eddsa_signature,
     477              :         &exchange_pub->eddsa_pub))
     478              :   {
     479            0 :     GNUNET_break_op (0);
     480            0 :     return GNUNET_SYSERR;
     481              :   }
     482            3 :   return GNUNET_OK;
     483              : }
     484              : 
     485              : 
     486              : enum GNUNET_GenericReturnValue
     487            0 : 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            0 :   struct TALER_WithdrawConfirmationPS confirm = {
     493            0 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WITHDRAW),
     494            0 :     .purpose.size = htonl (sizeof (confirm)),
     495              :     .h_planchets = *h_planchets,
     496            0 :     .noreveal_index = htonl (0xFFFFFFFF)
     497              :   };
     498              : 
     499            0 :   if (GNUNET_OK !=
     500            0 :       GNUNET_CRYPTO_eddsa_verify (
     501              :         TALER_SIGNATURE_EXCHANGE_CONFIRM_WITHDRAW,
     502              :         &confirm,
     503              :         &exchange_sig->eddsa_signature,
     504              :         &exchange_pub->eddsa_pub))
     505              :   {
     506            0 :     GNUNET_break_op (0);
     507            0 :     return GNUNET_SYSERR;
     508              :   }
     509            0 :   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           91 : 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          182 :   struct TALER_ExchangeKeySetPS ks = {
     553           91 :     .purpose.size = htonl (sizeof (ks)),
     554           91 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_KEY_SET),
     555           91 :     .list_issue_date = GNUNET_TIME_timestamp_hton (timestamp),
     556              :     .hc = *hc
     557              :   };
     558              : 
     559           91 :   return scb (cls,
     560              :               &ks.purpose,
     561              :               pub,
     562              :               sig);
     563              : }
     564              : 
     565              : 
     566              : enum GNUNET_GenericReturnValue
     567           34 : 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           68 :   struct TALER_ExchangeKeySetPS ks = {
     574           34 :     .purpose.size = htonl (sizeof (ks)),
     575           34 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_KEY_SET),
     576           34 :     .list_issue_date = GNUNET_TIME_timestamp_hton (timestamp),
     577              :     .hc = *hc
     578              :   };
     579              : 
     580              :   return
     581           34 :     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           34 : 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           68 :   struct TALER_WireDepositDetailP dd = {
     637              :     .h_contract_terms = *h_contract_terms,
     638           34 :     .execution_time = GNUNET_TIME_timestamp_hton (execution_time),
     639              :     .coin_pub = *coin_pub
     640              :   };
     641           34 :   TALER_amount_hton (&dd.deposit_value,
     642              :                      deposit_value);
     643           34 :   TALER_amount_hton (&dd.deposit_fee,
     644              :                      deposit_fee);
     645           34 :   GNUNET_CRYPTO_hash_context_read (hash_context,
     646              :                                    &dd,
     647              :                                    sizeof (dd));
     648           34 : }
     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            4 : 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            4 :   struct TALER_WireDepositDataPS wdp = {
     708            4 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT),
     709            4 :     .purpose.size = htonl (sizeof (wdp)),
     710              :     .merchant_pub = *merchant_pub,
     711              :     .h_details = *h_details
     712              :   };
     713              : 
     714            4 :   TALER_amount_hton (&wdp.total,
     715              :                      total);
     716            4 :   TALER_amount_hton (&wdp.wire_fee,
     717              :                      wire_fee);
     718            4 :   TALER_full_payto_hash (payto,
     719              :                          &wdp.h_payto);
     720            4 :   return scb (&wdp.purpose,
     721              :               pub,
     722              :               sig);
     723              : }
     724              : 
     725              : 
     726              : enum GNUNET_GenericReturnValue
     727            4 : 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            4 :   struct TALER_WireDepositDataPS wdp = {
     737            4 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT),
     738            4 :     .purpose.size = htonl (sizeof (wdp)),
     739              :     .merchant_pub = *merchant_pub,
     740              :     .h_details = *h_details,
     741              :     .h_payto = *h_payto
     742              :   };
     743              : 
     744            4 :   TALER_amount_hton (&wdp.total,
     745              :                      total);
     746            4 :   TALER_amount_hton (&wdp.wire_fee,
     747              :                      wire_fee);
     748            4 :   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            2 : 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            2 :   struct TALER_ConfirmWirePS cw = {
     823            2 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE),
     824            2 :     .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            2 :     .execution_time = GNUNET_TIME_timestamp_hton (execution_time)
     830              :   };
     831              : 
     832            2 :   TALER_amount_hton (&cw.coin_contribution,
     833              :                      coin_contribution);
     834            2 :   return scb (&cw.purpose,
     835              :               pub,
     836              :               sig);
     837              : }
     838              : 
     839              : 
     840              : enum GNUNET_GenericReturnValue
     841            2 : 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            2 :   struct TALER_ConfirmWirePS cw = {
     852            2 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE),
     853            2 :     .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            2 :     .execution_time = GNUNET_TIME_timestamp_hton (execution_time)
     859              :   };
     860              : 
     861            2 :   TALER_amount_hton (&cw.coin_contribution,
     862              :                      coin_contribution);
     863              :   return
     864            2 :     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            0 : 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            0 :   struct TALER_RecoupConfirmationPS pc = {
     925            0 :     .purpose.size = htonl (sizeof (pc)),
     926            0 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP),
     927            0 :     .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
     928              :     .coin_pub = *coin_pub,
     929              :     .reserve_pub = *reserve_pub
     930              :   };
     931              : 
     932            0 :   TALER_amount_hton (&pc.recoup_amount,
     933              :                      recoup_amount);
     934            0 :   return scb (&pc.purpose,
     935              :               pub,
     936              :               sig);
     937              : }
     938              : 
     939              : 
     940              : enum GNUNET_GenericReturnValue
     941            0 : 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            0 :   struct TALER_RecoupConfirmationPS pc = {
     950            0 :     .purpose.size = htonl (sizeof (pc)),
     951            0 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP),
     952            0 :     .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
     953              :     .coin_pub = *coin_pub,
     954              :     .reserve_pub = *reserve_pub
     955              :   };
     956              : 
     957            0 :   TALER_amount_hton (&pc.recoup_amount,
     958              :                      recoup_amount);
     959              :   return
     960            0 :     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            0 : 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            0 :   struct TALER_RecoupRefreshConfirmationPS pc = {
    1020            0 :     .purpose.purpose = htonl (
    1021              :       TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH),
    1022            0 :     .purpose.size = htonl (sizeof (pc)),
    1023            0 :     .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
    1024              :     .coin_pub = *coin_pub,
    1025              :     .old_coin_pub = *old_coin_pub
    1026              :   };
    1027              : 
    1028            0 :   TALER_amount_hton (&pc.recoup_amount,
    1029              :                      recoup_amount);
    1030            0 :   return scb (&pc.purpose,
    1031              :               pub,
    1032              :               sig);
    1033              : }
    1034              : 
    1035              : 
    1036              : enum GNUNET_GenericReturnValue
    1037            0 : 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            0 :   struct TALER_RecoupRefreshConfirmationPS pc = {
    1046            0 :     .purpose.purpose = htonl (
    1047              :       TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH),
    1048            0 :     .purpose.size = htonl (sizeof (pc)),
    1049            0 :     .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
    1050              :     .coin_pub = *coin_pub,
    1051              :     .old_coin_pub = *old_coin_pub
    1052              :   };
    1053              : 
    1054            0 :   TALER_amount_hton (&pc.recoup_amount,
    1055              :                      recoup_amount);
    1056              : 
    1057              :   return
    1058            0 :     GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH,
    1059              :                                 &pc,
    1060              :                                 &sig->eddsa_signature,
    1061              :                                 &pub->eddsa_pub);
    1062              : }
    1063              : 
    1064              : 
    1065              : GNUNET_NETWORK_STRUCT_BEGIN
    1066              : 
    1067              : /**
    1068              :  * Response by which the exchange affirms that it does not
    1069              :  * currently know a denomination by the given hash.
    1070              :  */
    1071              : struct TALER_DenominationUnknownAffirmationPS
    1072              : {
    1073              : 
    1074              :   /**
    1075              :    * Purpose is #TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN
    1076              :    */
    1077              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    1078              : 
    1079              :   /**
    1080              :    * When did the exchange sign this message.
    1081              :    */
    1082              :   struct GNUNET_TIME_TimestampNBO timestamp;
    1083              : 
    1084              :   /**
    1085              :    * Hash of the public denomination key we do not know.
    1086              :    */
    1087              :   struct TALER_DenominationHashP h_denom_pub;
    1088              : };
    1089              : 
    1090              : GNUNET_NETWORK_STRUCT_END
    1091              : 
    1092              : 
    1093              : enum TALER_ErrorCode
    1094            0 : TALER_exchange_online_denomination_unknown_sign (
    1095              :   TALER_ExchangeSignCallback scb,
    1096              :   struct GNUNET_TIME_Timestamp timestamp,
    1097              :   const struct TALER_DenominationHashP *h_denom_pub,
    1098              :   struct TALER_ExchangePublicKeyP *pub,
    1099              :   struct TALER_ExchangeSignatureP *sig)
    1100              : {
    1101            0 :   struct TALER_DenominationUnknownAffirmationPS dua = {
    1102            0 :     .purpose.size = htonl (sizeof (dua)),
    1103            0 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN),
    1104            0 :     .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
    1105              :     .h_denom_pub = *h_denom_pub,
    1106              :   };
    1107              : 
    1108            0 :   return scb (&dua.purpose,
    1109              :               pub,
    1110              :               sig);
    1111              : }
    1112              : 
    1113              : 
    1114              : enum GNUNET_GenericReturnValue
    1115            0 : TALER_exchange_online_denomination_unknown_verify (
    1116              :   struct GNUNET_TIME_Timestamp timestamp,
    1117              :   const struct TALER_DenominationHashP *h_denom_pub,
    1118              :   const struct TALER_ExchangePublicKeyP *pub,
    1119              :   const struct TALER_ExchangeSignatureP *sig)
    1120              : {
    1121            0 :   struct TALER_DenominationUnknownAffirmationPS dua = {
    1122            0 :     .purpose.size = htonl (sizeof (dua)),
    1123            0 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN),
    1124            0 :     .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
    1125              :     .h_denom_pub = *h_denom_pub,
    1126              :   };
    1127              : 
    1128              :   return
    1129            0 :     GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN,
    1130              :                                 &dua,
    1131              :                                 &sig->eddsa_signature,
    1132              :                                 &pub->eddsa_pub);
    1133              : }
    1134              : 
    1135              : 
    1136              : GNUNET_NETWORK_STRUCT_BEGIN
    1137              : 
    1138              : /**
    1139              :  * Response by which the exchange affirms that it does not
    1140              :  * currently consider the given denomination to be valid
    1141              :  * for the requested operation.
    1142              :  */
    1143              : struct TALER_DenominationExpiredAffirmationPS
    1144              : {
    1145              : 
    1146              :   /**
    1147              :    * Purpose is #TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED
    1148              :    */
    1149              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    1150              : 
    1151              :   /**
    1152              :    * When did the exchange sign this message.
    1153              :    */
    1154              :   struct GNUNET_TIME_TimestampNBO timestamp;
    1155              : 
    1156              :   /**
    1157              :    * Name of the operation that is not allowed at this time.  Might NOT be 0-terminated, but is padded with 0s.
    1158              :    */
    1159              :   char operation[8];
    1160              : 
    1161              :   /**
    1162              :    * Hash of the public denomination key we do not know.
    1163              :    */
    1164              :   struct TALER_DenominationHashP h_denom_pub;
    1165              : 
    1166              : };
    1167              : 
    1168              : GNUNET_NETWORK_STRUCT_END
    1169              : 
    1170              : 
    1171              : enum TALER_ErrorCode
    1172            0 : TALER_exchange_online_denomination_expired_sign (
    1173              :   TALER_ExchangeSignCallback scb,
    1174              :   struct GNUNET_TIME_Timestamp timestamp,
    1175              :   const struct TALER_DenominationHashP *h_denom_pub,
    1176              :   const char *op,
    1177              :   struct TALER_ExchangePublicKeyP *pub,
    1178              :   struct TALER_ExchangeSignatureP *sig)
    1179              : {
    1180            0 :   struct TALER_DenominationExpiredAffirmationPS dua = {
    1181            0 :     .purpose.size = htonl (sizeof (dua)),
    1182            0 :     .purpose.purpose = htonl (
    1183              :       TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED),
    1184            0 :     .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
    1185              :     .h_denom_pub = *h_denom_pub,
    1186              :   };
    1187              : 
    1188              :   /* strncpy would create a compiler warning */
    1189            0 :   GNUNET_memcpy (dua.operation,
    1190              :                  op,
    1191              :                  GNUNET_MIN (sizeof (dua.operation),
    1192              :                              strlen (op)));
    1193            0 :   return scb (&dua.purpose,
    1194              :               pub,
    1195              :               sig);
    1196              : }
    1197              : 
    1198              : 
    1199              : enum GNUNET_GenericReturnValue
    1200            0 : TALER_exchange_online_denomination_expired_verify (
    1201              :   struct GNUNET_TIME_Timestamp timestamp,
    1202              :   const struct TALER_DenominationHashP *h_denom_pub,
    1203              :   const char *op,
    1204              :   const struct TALER_ExchangePublicKeyP *pub,
    1205              :   const struct TALER_ExchangeSignatureP *sig)
    1206              : {
    1207            0 :   struct TALER_DenominationExpiredAffirmationPS dua = {
    1208            0 :     .purpose.size = htonl (sizeof (dua)),
    1209            0 :     .purpose.purpose = htonl (
    1210              :       TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED),
    1211            0 :     .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
    1212              :     .h_denom_pub = *h_denom_pub,
    1213              :   };
    1214              : 
    1215              :   /* strncpy would create a compiler warning */
    1216            0 :   GNUNET_memcpy (dua.operation,
    1217              :                  op,
    1218              :                  GNUNET_MIN (sizeof (dua.operation),
    1219              :                              strlen (op)));
    1220              :   return
    1221            0 :     GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED,
    1222              :                                 &dua,
    1223              :                                 &sig->eddsa_signature,
    1224              :                                 &pub->eddsa_pub);
    1225              : }
    1226              : 
    1227              : 
    1228              : GNUNET_NETWORK_STRUCT_BEGIN
    1229              : 
    1230              : /**
    1231              :  * Response by which the exchange affirms that it has
    1232              :  * closed a reserve and send back the funds.
    1233              :  */
    1234              : struct TALER_ReserveCloseConfirmationPS
    1235              : {
    1236              : 
    1237              :   /**
    1238              :    * Purpose is #TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED
    1239              :    */
    1240              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    1241              : 
    1242              :   /**
    1243              :    * When did the exchange initiate the wire transfer.
    1244              :    */
    1245              :   struct GNUNET_TIME_TimestampNBO timestamp;
    1246              : 
    1247              :   /**
    1248              :    * How much did the exchange send?
    1249              :    */
    1250              :   struct TALER_AmountNBO closing_amount;
    1251              : 
    1252              :   /**
    1253              :    * How much did the exchange charge for closing the reserve?
    1254              :    */
    1255              :   struct TALER_AmountNBO closing_fee;
    1256              : 
    1257              :   /**
    1258              :    * Public key of the reserve that was closed.
    1259              :    */
    1260              :   struct TALER_ReservePublicKeyP reserve_pub;
    1261              : 
    1262              :   /**
    1263              :    * Hash of the receiver's bank account.
    1264              :    */
    1265              :   struct TALER_FullPaytoHashP h_payto;
    1266              : 
    1267              :   /**
    1268              :    * Wire transfer subject.
    1269              :    */
    1270              :   struct TALER_WireTransferIdentifierRawP wtid;
    1271              : };
    1272              : 
    1273              : GNUNET_NETWORK_STRUCT_END
    1274              : 
    1275              : 
    1276              : enum TALER_ErrorCode
    1277            0 : TALER_exchange_online_reserve_closed_sign (
    1278              :   TALER_ExchangeSignCallback scb,
    1279              :   struct GNUNET_TIME_Timestamp timestamp,
    1280              :   const struct TALER_Amount *closing_amount,
    1281              :   const struct TALER_Amount *closing_fee,
    1282              :   const struct TALER_FullPayto payto,
    1283              :   const struct TALER_WireTransferIdentifierRawP *wtid,
    1284              :   const struct TALER_ReservePublicKeyP *reserve_pub,
    1285              :   struct TALER_ExchangePublicKeyP *pub,
    1286              :   struct TALER_ExchangeSignatureP *sig)
    1287              : {
    1288            0 :   struct TALER_ReserveCloseConfirmationPS rcc = {
    1289            0 :     .purpose.size = htonl (sizeof (rcc)),
    1290            0 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED),
    1291              :     .wtid = *wtid,
    1292              :     .reserve_pub = *reserve_pub,
    1293            0 :     .timestamp = GNUNET_TIME_timestamp_hton (timestamp)
    1294              :   };
    1295              : 
    1296            0 :   TALER_amount_hton (&rcc.closing_amount,
    1297              :                      closing_amount);
    1298            0 :   TALER_amount_hton (&rcc.closing_fee,
    1299              :                      closing_fee);
    1300            0 :   TALER_full_payto_hash (payto,
    1301              :                          &rcc.h_payto);
    1302            0 :   return scb (&rcc.purpose,
    1303              :               pub,
    1304              :               sig);
    1305              : }
    1306              : 
    1307              : 
    1308              : enum GNUNET_GenericReturnValue
    1309            0 : TALER_exchange_online_reserve_closed_verify (
    1310              :   struct GNUNET_TIME_Timestamp timestamp,
    1311              :   const struct TALER_Amount *closing_amount,
    1312              :   const struct TALER_Amount *closing_fee,
    1313              :   const struct TALER_FullPayto payto,
    1314              :   const struct TALER_WireTransferIdentifierRawP *wtid,
    1315              :   const struct TALER_ReservePublicKeyP *reserve_pub,
    1316              :   const struct TALER_ExchangePublicKeyP *pub,
    1317              :   const struct TALER_ExchangeSignatureP *sig)
    1318              : {
    1319            0 :   struct TALER_ReserveCloseConfirmationPS rcc = {
    1320            0 :     .purpose.size = htonl (sizeof (rcc)),
    1321            0 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED),
    1322              :     .wtid = *wtid,
    1323              :     .reserve_pub = *reserve_pub,
    1324            0 :     .timestamp = GNUNET_TIME_timestamp_hton (timestamp)
    1325              :   };
    1326              : 
    1327            0 :   TALER_amount_hton (&rcc.closing_amount,
    1328              :                      closing_amount);
    1329            0 :   TALER_amount_hton (&rcc.closing_fee,
    1330              :                      closing_fee);
    1331            0 :   TALER_full_payto_hash (payto,
    1332              :                          &rcc.h_payto);
    1333            0 :   return GNUNET_CRYPTO_eddsa_verify (
    1334              :     TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED,
    1335              :     &rcc,
    1336              :     &sig->eddsa_signature,
    1337              :     &pub->eddsa_pub);
    1338              : }
    1339              : 
    1340              : 
    1341              : GNUNET_NETWORK_STRUCT_BEGIN
    1342              : 
    1343              : /**
    1344              :  * Response by which the exchange affirms that it has
    1345              :  * received funds deposited into a purse.
    1346              :  */
    1347              : struct TALER_PurseCreateDepositConfirmationPS
    1348              : {
    1349              : 
    1350              :   /**
    1351              :    * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_CREATION
    1352              :    */
    1353              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    1354              : 
    1355              :   /**
    1356              :    * When did the exchange receive the deposits.
    1357              :    */
    1358              :   struct GNUNET_TIME_TimestampNBO exchange_time;
    1359              : 
    1360              :   /**
    1361              :    * When will the purse expire?
    1362              :    */
    1363              :   struct GNUNET_TIME_TimestampNBO purse_expiration;
    1364              : 
    1365              :   /**
    1366              :    * How much should the purse ultimately contain.
    1367              :    */
    1368              :   struct TALER_AmountNBO amount_without_fee;
    1369              : 
    1370              :   /**
    1371              :    * How much was deposited so far.
    1372              :    */
    1373              :   struct TALER_AmountNBO total_deposited;
    1374              : 
    1375              :   /**
    1376              :    * Public key of the purse.
    1377              :    */
    1378              :   struct TALER_PurseContractPublicKeyP purse_pub;
    1379              : 
    1380              :   /**
    1381              :    * Hash of the contract of the purse.
    1382              :    */
    1383              :   struct TALER_PrivateContractHashP h_contract_terms;
    1384              : 
    1385              : };
    1386              : 
    1387              : GNUNET_NETWORK_STRUCT_END
    1388              : 
    1389              : 
    1390              : enum TALER_ErrorCode
    1391           25 : TALER_exchange_online_purse_created_sign (
    1392              :   TALER_ExchangeSignCallback scb,
    1393              :   struct GNUNET_TIME_Timestamp exchange_time,
    1394              :   struct GNUNET_TIME_Timestamp purse_expiration,
    1395              :   const struct TALER_Amount *amount_without_fee,
    1396              :   const struct TALER_Amount *total_deposited,
    1397              :   const struct TALER_PurseContractPublicKeyP *purse_pub,
    1398              :   const struct TALER_PrivateContractHashP *h_contract_terms,
    1399              :   struct TALER_ExchangePublicKeyP *pub,
    1400              :   struct TALER_ExchangeSignatureP *sig)
    1401              : {
    1402           50 :   struct TALER_PurseCreateDepositConfirmationPS dc = {
    1403           25 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_CREATION),
    1404           25 :     .purpose.size = htonl (sizeof (dc)),
    1405              :     .h_contract_terms = *h_contract_terms,
    1406              :     .purse_pub = *purse_pub,
    1407           25 :     .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
    1408           25 :     .exchange_time = GNUNET_TIME_timestamp_hton (exchange_time)
    1409              :   };
    1410              : 
    1411           25 :   TALER_amount_hton (&dc.amount_without_fee,
    1412              :                      amount_without_fee);
    1413           25 :   TALER_amount_hton (&dc.total_deposited,
    1414              :                      total_deposited);
    1415           25 :   return scb (&dc.purpose,
    1416              :               pub,
    1417              :               sig);
    1418              : }
    1419              : 
    1420              : 
    1421              : enum GNUNET_GenericReturnValue
    1422           25 : TALER_exchange_online_purse_created_verify (
    1423              :   struct GNUNET_TIME_Timestamp exchange_time,
    1424              :   struct GNUNET_TIME_Timestamp purse_expiration,
    1425              :   const struct TALER_Amount *amount_without_fee,
    1426              :   const struct TALER_Amount *total_deposited,
    1427              :   const struct TALER_PurseContractPublicKeyP *purse_pub,
    1428              :   const struct TALER_PrivateContractHashP *h_contract_terms,
    1429              :   const struct TALER_ExchangePublicKeyP *pub,
    1430              :   const struct TALER_ExchangeSignatureP *sig)
    1431              : {
    1432           50 :   struct TALER_PurseCreateDepositConfirmationPS dc = {
    1433           25 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_CREATION),
    1434           25 :     .purpose.size = htonl (sizeof (dc)),
    1435              :     .h_contract_terms = *h_contract_terms,
    1436              :     .purse_pub = *purse_pub,
    1437           25 :     .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
    1438           25 :     .exchange_time = GNUNET_TIME_timestamp_hton (exchange_time)
    1439              :   };
    1440              : 
    1441           25 :   TALER_amount_hton (&dc.amount_without_fee,
    1442              :                      amount_without_fee);
    1443           25 :   TALER_amount_hton (&dc.total_deposited,
    1444              :                      total_deposited);
    1445           25 :   return GNUNET_CRYPTO_eddsa_verify (
    1446              :     TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_CREATION,
    1447              :     &dc,
    1448              :     &sig->eddsa_signature,
    1449              :     &pub->eddsa_pub);
    1450              : }
    1451              : 
    1452              : 
    1453              : GNUNET_NETWORK_STRUCT_BEGIN
    1454              : 
    1455              : /**
    1456              :  * Response by which the exchange affirms that it has
    1457              :  * received funds deposited into a purse.
    1458              :  */
    1459              : struct TALER_CoinPurseRefundConfirmationPS
    1460              : {
    1461              : 
    1462              :   /**
    1463              :    * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_REFUND
    1464              :    */
    1465              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    1466              : 
    1467              :   /**
    1468              :    * Public key of the purse.
    1469              :    */
    1470              :   struct TALER_PurseContractPublicKeyP purse_pub;
    1471              : 
    1472              :   /**
    1473              :    * Public key of the coin.
    1474              :    */
    1475              :   struct TALER_CoinSpendPublicKeyP coin_pub;
    1476              : 
    1477              :   /**
    1478              :    * How much will be refunded to the purse.
    1479              :    */
    1480              :   struct TALER_AmountNBO refunded_amount;
    1481              : 
    1482              :   /**
    1483              :    * How much was the refund fee.
    1484              :    */
    1485              :   struct TALER_AmountNBO refund_fee;
    1486              : 
    1487              : };
    1488              : 
    1489              : GNUNET_NETWORK_STRUCT_END
    1490              : 
    1491              : 
    1492              : enum TALER_ErrorCode
    1493            0 : TALER_exchange_online_purse_refund_sign (
    1494              :   TALER_ExchangeSignCallback scb,
    1495              :   const struct TALER_Amount *amount_without_fee,
    1496              :   const struct TALER_Amount *refund_fee,
    1497              :   const struct TALER_CoinSpendPublicKeyP *coin_pub,
    1498              :   const struct TALER_PurseContractPublicKeyP *purse_pub,
    1499              :   struct TALER_ExchangePublicKeyP *pub,
    1500              :   struct TALER_ExchangeSignatureP *sig)
    1501              : {
    1502            0 :   struct TALER_CoinPurseRefundConfirmationPS dc = {
    1503            0 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_REFUND),
    1504            0 :     .purpose.size = htonl (sizeof (dc)),
    1505              :     .coin_pub = *coin_pub,
    1506              :     .purse_pub = *purse_pub,
    1507              :   };
    1508              : 
    1509            0 :   TALER_amount_hton (&dc.refunded_amount,
    1510              :                      amount_without_fee);
    1511            0 :   TALER_amount_hton (&dc.refund_fee,
    1512              :                      refund_fee);
    1513            0 :   return scb (&dc.purpose,
    1514              :               pub,
    1515              :               sig);
    1516              : }
    1517              : 
    1518              : 
    1519              : enum GNUNET_GenericReturnValue
    1520            0 : TALER_exchange_online_purse_refund_verify (
    1521              :   const struct TALER_Amount *amount_without_fee,
    1522              :   const struct TALER_Amount *refund_fee,
    1523              :   const struct TALER_CoinSpendPublicKeyP *coin_pub,
    1524              :   const struct TALER_PurseContractPublicKeyP *purse_pub,
    1525              :   const struct TALER_ExchangePublicKeyP *pub,
    1526              :   const struct TALER_ExchangeSignatureP *sig)
    1527              : {
    1528            0 :   struct TALER_CoinPurseRefundConfirmationPS dc = {
    1529            0 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_REFUND),
    1530            0 :     .purpose.size = htonl (sizeof (dc)),
    1531              :     .coin_pub = *coin_pub,
    1532              :     .purse_pub = *purse_pub,
    1533              :   };
    1534              : 
    1535            0 :   TALER_amount_hton (&dc.refunded_amount,
    1536              :                      amount_without_fee);
    1537            0 :   TALER_amount_hton (&dc.refund_fee,
    1538              :                      refund_fee);
    1539            0 :   return GNUNET_CRYPTO_eddsa_verify (
    1540              :     TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_REFUND,
    1541              :     &dc,
    1542              :     &sig->eddsa_signature,
    1543              :     &pub->eddsa_pub);
    1544              : }
    1545              : 
    1546              : 
    1547              : GNUNET_NETWORK_STRUCT_BEGIN
    1548              : 
    1549              : /**
    1550              :  * Response by which the exchange affirms that it has
    1551              :  * merged a purse into a reserve.
    1552              :  */
    1553              : struct TALER_PurseMergedConfirmationPS
    1554              : {
    1555              : 
    1556              :   /**
    1557              :    * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_MERGED
    1558              :    */
    1559              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    1560              : 
    1561              :   /**
    1562              :    * When did the exchange receive the deposits.
    1563              :    */
    1564              :   struct GNUNET_TIME_TimestampNBO exchange_time;
    1565              : 
    1566              :   /**
    1567              :    * When will the purse expire?
    1568              :    */
    1569              :   struct GNUNET_TIME_TimestampNBO purse_expiration;
    1570              : 
    1571              :   /**
    1572              :    * How much should the purse ultimately contain.
    1573              :    */
    1574              :   struct TALER_AmountNBO amount_without_fee;
    1575              : 
    1576              :   /**
    1577              :    * Public key of the purse.
    1578              :    */
    1579              :   struct TALER_PurseContractPublicKeyP purse_pub;
    1580              : 
    1581              :   /**
    1582              :    * Public key of the reserve.
    1583              :    */
    1584              :   struct TALER_ReservePublicKeyP reserve_pub;
    1585              : 
    1586              :   /**
    1587              :    * Hash of the contract of the purse.
    1588              :    */
    1589              :   struct TALER_PrivateContractHashP h_contract_terms;
    1590              : 
    1591              :   /**
    1592              :    * Hash of the provider URL hosting the reserve.
    1593              :    */
    1594              :   struct GNUNET_HashCode h_provider_url;
    1595              : 
    1596              : };
    1597              : 
    1598              : GNUNET_NETWORK_STRUCT_END
    1599              : 
    1600              : 
    1601              : enum TALER_ErrorCode
    1602            3 : TALER_exchange_online_purse_merged_sign (
    1603              :   TALER_ExchangeSignCallback scb,
    1604              :   struct GNUNET_TIME_Timestamp exchange_time,
    1605              :   struct GNUNET_TIME_Timestamp purse_expiration,
    1606              :   const struct TALER_Amount *amount_without_fee,
    1607              :   const struct TALER_PurseContractPublicKeyP *purse_pub,
    1608              :   const struct TALER_PrivateContractHashP *h_contract_terms,
    1609              :   const struct TALER_ReservePublicKeyP *reserve_pub,
    1610              :   const char *exchange_url,
    1611              :   struct TALER_ExchangePublicKeyP *pub,
    1612              :   struct TALER_ExchangeSignatureP *sig)
    1613              : {
    1614            6 :   struct TALER_PurseMergedConfirmationPS dc = {
    1615            3 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_MERGED),
    1616            3 :     .purpose.size = htonl (sizeof (dc)),
    1617              :     .h_contract_terms = *h_contract_terms,
    1618              :     .purse_pub = *purse_pub,
    1619              :     .reserve_pub = *reserve_pub,
    1620            3 :     .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
    1621            3 :     .exchange_time = GNUNET_TIME_timestamp_hton (exchange_time)
    1622              :   };
    1623              : 
    1624            3 :   TALER_amount_hton (&dc.amount_without_fee,
    1625              :                      amount_without_fee);
    1626            3 :   GNUNET_CRYPTO_hash (exchange_url,
    1627            3 :                       strlen (exchange_url) + 1,
    1628              :                       &dc.h_provider_url);
    1629            3 :   return scb (&dc.purpose,
    1630              :               pub,
    1631              :               sig);
    1632              : }
    1633              : 
    1634              : 
    1635              : enum GNUNET_GenericReturnValue
    1636            3 : TALER_exchange_online_purse_merged_verify (
    1637              :   struct GNUNET_TIME_Timestamp exchange_time,
    1638              :   struct GNUNET_TIME_Timestamp purse_expiration,
    1639              :   const struct TALER_Amount *amount_without_fee,
    1640              :   const struct TALER_PurseContractPublicKeyP *purse_pub,
    1641              :   const struct TALER_PrivateContractHashP *h_contract_terms,
    1642              :   const struct TALER_ReservePublicKeyP *reserve_pub,
    1643              :   const char *exchange_url,
    1644              :   const struct TALER_ExchangePublicKeyP *pub,
    1645              :   const struct TALER_ExchangeSignatureP *sig)
    1646              : {
    1647            6 :   struct TALER_PurseMergedConfirmationPS dc = {
    1648            3 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_MERGED),
    1649            3 :     .purpose.size = htonl (sizeof (dc)),
    1650              :     .h_contract_terms = *h_contract_terms,
    1651              :     .purse_pub = *purse_pub,
    1652              :     .reserve_pub = *reserve_pub,
    1653            3 :     .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
    1654            3 :     .exchange_time = GNUNET_TIME_timestamp_hton (exchange_time)
    1655              :   };
    1656              : 
    1657            3 :   TALER_amount_hton (&dc.amount_without_fee,
    1658              :                      amount_without_fee);
    1659            3 :   GNUNET_CRYPTO_hash (exchange_url,
    1660            3 :                       strlen (exchange_url) + 1,
    1661              :                       &dc.h_provider_url);
    1662              :   return
    1663            3 :     GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_MERGED,
    1664              :                                 &dc,
    1665              :                                 &sig->eddsa_signature,
    1666              :                                 &pub->eddsa_pub);
    1667              : }
    1668              : 
    1669              : 
    1670              : GNUNET_NETWORK_STRUCT_BEGIN
    1671              : 
    1672              : /**
    1673              :  * @brief Format used to generate the signature on a purse status
    1674              :  * from the exchange.
    1675              :  */
    1676              : struct TALER_PurseStatusPS
    1677              : {
    1678              :   /**
    1679              :    * Purpose must be #TALER_SIGNATURE_EXCHANGE_PURSE_STATUS.  Signed
    1680              :    * by a `struct TALER_ExchangePublicKeyP` using EdDSA.
    1681              :    */
    1682              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    1683              : 
    1684              :   /**
    1685              :    * Time when the purse was merged, possibly 'never'.
    1686              :    */
    1687              :   struct GNUNET_TIME_TimestampNBO merge_timestamp;
    1688              : 
    1689              :   /**
    1690              :    * Time when the purse was deposited last, possibly 'never'.
    1691              :    */
    1692              :   struct GNUNET_TIME_TimestampNBO deposit_timestamp;
    1693              : 
    1694              :   /**
    1695              :    * Amount deposited in total in the purse without fees.
    1696              :    * May be possibly less than the target amount.
    1697              :    */
    1698              :   struct TALER_AmountNBO balance;
    1699              : 
    1700              : };
    1701              : 
    1702              : GNUNET_NETWORK_STRUCT_END
    1703              : 
    1704              : 
    1705              : enum TALER_ErrorCode
    1706            6 : TALER_exchange_online_purse_status_sign (
    1707              :   TALER_ExchangeSignCallback scb,
    1708              :   struct GNUNET_TIME_Timestamp merge_timestamp,
    1709              :   struct GNUNET_TIME_Timestamp deposit_timestamp,
    1710              :   const struct TALER_Amount *balance,
    1711              :   struct TALER_ExchangePublicKeyP *pub,
    1712              :   struct TALER_ExchangeSignatureP *sig)
    1713              : {
    1714            6 :   struct TALER_PurseStatusPS dcs = {
    1715            6 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_PURSE_STATUS),
    1716            6 :     .purpose.size = htonl (sizeof (dcs)),
    1717            6 :     .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp),
    1718            6 :     .deposit_timestamp = GNUNET_TIME_timestamp_hton (deposit_timestamp)
    1719              :   };
    1720              : 
    1721            6 :   TALER_amount_hton (&dcs.balance,
    1722              :                      balance);
    1723            6 :   return scb (&dcs.purpose,
    1724              :               pub,
    1725              :               sig);
    1726              : }
    1727              : 
    1728              : 
    1729              : enum GNUNET_GenericReturnValue
    1730            6 : TALER_exchange_online_purse_status_verify (
    1731              :   struct GNUNET_TIME_Timestamp merge_timestamp,
    1732              :   struct GNUNET_TIME_Timestamp deposit_timestamp,
    1733              :   const struct TALER_Amount *balance,
    1734              :   const struct TALER_ExchangePublicKeyP *exchange_pub,
    1735              :   const struct TALER_ExchangeSignatureP *exchange_sig)
    1736              : {
    1737            6 :   struct TALER_PurseStatusPS dcs = {
    1738            6 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_PURSE_STATUS),
    1739            6 :     .purpose.size = htonl (sizeof (dcs)),
    1740            6 :     .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp),
    1741            6 :     .deposit_timestamp = GNUNET_TIME_timestamp_hton (deposit_timestamp)
    1742              :   };
    1743              : 
    1744            6 :   TALER_amount_hton (&dcs.balance,
    1745              :                      balance);
    1746            6 :   if (GNUNET_OK !=
    1747            6 :       GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_PURSE_STATUS,
    1748              :                                   &dcs,
    1749              :                                   &exchange_sig->eddsa_signature,
    1750              :                                   &exchange_pub->eddsa_pub))
    1751              :   {
    1752            0 :     GNUNET_break_op (0);
    1753            0 :     return GNUNET_SYSERR;
    1754              :   }
    1755            6 :   return GNUNET_OK;
    1756              : }
    1757              : 
    1758              : 
    1759              : GNUNET_NETWORK_STRUCT_BEGIN
    1760              : 
    1761              : /**
    1762              :  * Message signed by the exchange to affirm that the
    1763              :  * owner of a reserve has certain attributes.
    1764              :  */
    1765              : struct TALER_ExchangeAttestPS
    1766              : {
    1767              : 
    1768              :   /**
    1769              :    * Purpose is #TALER_SIGNATURE_EXCHANGE_RESERVE_ATTEST_DETAILS
    1770              :    */
    1771              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    1772              : 
    1773              :   /**
    1774              :    * Time when the attestation was made.
    1775              :    */
    1776              :   struct GNUNET_TIME_TimestampNBO attest_timestamp;
    1777              : 
    1778              :   /**
    1779              :    * Time when the attestation expires.
    1780              :    */
    1781              :   struct GNUNET_TIME_TimestampNBO expiration_time;
    1782              : 
    1783              :   /**
    1784              :    * Public key of the reserve for which the attributes
    1785              :    * are attested.
    1786              :    */
    1787              :   struct TALER_ReservePublicKeyP reserve_pub;
    1788              : 
    1789              :   /**
    1790              :    * Hash over the attributes.
    1791              :    */
    1792              :   struct GNUNET_HashCode h_attributes;
    1793              : 
    1794              : };
    1795              : 
    1796              : GNUNET_NETWORK_STRUCT_END
    1797              : 
    1798              : 
    1799              : enum TALER_ErrorCode
    1800            1 : TALER_exchange_online_reserve_attest_details_sign (
    1801              :   TALER_ExchangeSignCallback scb,
    1802              :   struct GNUNET_TIME_Timestamp attest_timestamp,
    1803              :   struct GNUNET_TIME_Timestamp expiration_time,
    1804              :   const struct TALER_ReservePublicKeyP *reserve_pub,
    1805              :   const json_t *attributes,
    1806              :   struct TALER_ExchangePublicKeyP *pub,
    1807              :   struct TALER_ExchangeSignatureP *sig)
    1808              : {
    1809            2 :   struct TALER_ExchangeAttestPS rap = {
    1810            1 :     .purpose.size = htonl (sizeof (rap)),
    1811            1 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_ATTEST_DETAILS),
    1812            1 :     .attest_timestamp = GNUNET_TIME_timestamp_hton (attest_timestamp),
    1813            1 :     .expiration_time = GNUNET_TIME_timestamp_hton (expiration_time),
    1814              :     .reserve_pub = *reserve_pub
    1815              :   };
    1816              : 
    1817            1 :   TALER_json_hash (attributes,
    1818              :                    &rap.h_attributes);
    1819            1 :   return scb (&rap.purpose,
    1820              :               pub,
    1821              :               sig);
    1822              : }
    1823              : 
    1824              : 
    1825              : enum GNUNET_GenericReturnValue
    1826            1 : TALER_exchange_online_reserve_attest_details_verify (
    1827              :   struct GNUNET_TIME_Timestamp attest_timestamp,
    1828              :   struct GNUNET_TIME_Timestamp expiration_time,
    1829              :   const struct TALER_ReservePublicKeyP *reserve_pub,
    1830              :   const json_t *attributes,
    1831              :   struct TALER_ExchangePublicKeyP *pub,
    1832              :   struct TALER_ExchangeSignatureP *sig)
    1833              : {
    1834            2 :   struct TALER_ExchangeAttestPS rap = {
    1835            1 :     .purpose.size = htonl (sizeof (rap)),
    1836            1 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_ATTEST_DETAILS),
    1837            1 :     .attest_timestamp = GNUNET_TIME_timestamp_hton (attest_timestamp),
    1838            1 :     .expiration_time = GNUNET_TIME_timestamp_hton (expiration_time),
    1839              :     .reserve_pub = *reserve_pub
    1840              :   };
    1841              : 
    1842            1 :   TALER_json_hash (attributes,
    1843              :                    &rap.h_attributes);
    1844            1 :   if (GNUNET_OK !=
    1845            1 :       GNUNET_CRYPTO_eddsa_verify (
    1846              :         TALER_SIGNATURE_EXCHANGE_RESERVE_ATTEST_DETAILS,
    1847              :         &rap,
    1848              :         &sig->eddsa_signature,
    1849              :         &pub->eddsa_pub))
    1850              :   {
    1851            0 :     GNUNET_break_op (0);
    1852            0 :     return GNUNET_SYSERR;
    1853              :   }
    1854            1 :   return GNUNET_OK;
    1855              : }
    1856              : 
    1857              : 
    1858              : /* end of exchange_signatures.c */
        

Generated by: LCOV version 2.0-1