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

Generated by: LCOV version 2.0-1