LCOV - code coverage report
Current view: top level - util - exchange_signatures.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 199 312 63.8 %
Date: 2025-06-05 21:03:14 Functions: 23 37 62.2 %

          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 "platform.h"
      22             : #include "taler_util.h"
      23             : #include "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_EccSignaturePurpose 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          90 : 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          90 : {
     115         180 :   struct TALER_DepositConfirmationPS dcs = {
     116          90 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT),
     117          90 :     .purpose.size = htonl (sizeof (struct TALER_DepositConfirmationPS)),
     118             :     .h_contract_terms = *h_contract_terms,
     119             :     .h_wire = *h_wire,
     120          90 :     .exchange_timestamp = GNUNET_TIME_timestamp_hton (exchange_timestamp),
     121          90 :     .wire_deadline = GNUNET_TIME_timestamp_hton (wire_deadline),
     122          90 :     .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          90 :   hc = GNUNET_CRYPTO_hash_context_start ();
     129         182 :   for (unsigned int i = 0; i<num_coins; i++)
     130          92 :     GNUNET_CRYPTO_hash_context_read (hc,
     131          92 :                                      coin_sigs[i],
     132             :                                      sizeof (*coin_sigs[i]));
     133          90 :   GNUNET_CRYPTO_hash_context_finish (hc,
     134             :                                      &dcs.h_coin_sigs);
     135          90 :   if (NULL != h_policy)
     136           0 :     dcs.h_policy = *h_policy;
     137          90 :   TALER_amount_hton (&dcs.total_without_fee,
     138             :                      total_without_fee);
     139          90 :   return scb (&dcs.purpose,
     140             :               pub,
     141             :               sig);
     142             : }
     143             : 
     144             : 
     145             : enum GNUNET_GenericReturnValue
     146         110 : 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         110 : {
     160         220 :   struct TALER_DepositConfirmationPS dcs = {
     161         110 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT),
     162         110 :     .purpose.size = htonl (sizeof (struct TALER_DepositConfirmationPS)),
     163             :     .h_contract_terms = *h_contract_terms,
     164             :     .h_wire = *h_wire,
     165         110 :     .exchange_timestamp = GNUNET_TIME_timestamp_hton (exchange_timestamp),
     166         110 :     .wire_deadline = GNUNET_TIME_timestamp_hton (wire_deadline),
     167         110 :     .refund_deadline = GNUNET_TIME_timestamp_hton (refund_deadline),
     168             :     .merchant_pub = *merchant_pub
     169             :   };
     170             :   struct GNUNET_HashContext *hc;
     171             : 
     172         110 :   hc = GNUNET_CRYPTO_hash_context_start ();
     173         222 :   for (unsigned int i = 0; i<num_coins; i++)
     174         112 :     GNUNET_CRYPTO_hash_context_read (hc,
     175         112 :                                      coin_sigs[i],
     176             :                                      sizeof (*coin_sigs[i]));
     177         110 :   GNUNET_CRYPTO_hash_context_finish (hc,
     178             :                                      &dcs.h_coin_sigs);
     179         110 :   if (NULL != h_policy)
     180         110 :     dcs.h_policy = *h_policy;
     181         110 :   TALER_amount_hton (&dcs.total_without_fee,
     182             :                      total_without_fee);
     183         110 :   if (GNUNET_OK !=
     184         110 :       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         110 :   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_EccSignaturePurpose 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          12 : 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          24 :   struct TALER_RefundConfirmationPS rc = {
     254          12 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND),
     255          12 :     .purpose.size = htonl (sizeof (rc)),
     256             :     .h_contract_terms = *h_contract_terms,
     257             :     .coin_pub = *coin_pub,
     258             :     .merchant = *merchant,
     259          12 :     .rtransaction_id = GNUNET_htonll (rtransaction_id)
     260             :   };
     261             : 
     262          12 :   TALER_amount_hton (&rc.refund_amount,
     263             :                      refund_amount);
     264          12 :   return scb (&rc.purpose,
     265             :               pub,
     266             :               sig);
     267             : }
     268             : 
     269             : 
     270             : enum GNUNET_GenericReturnValue
     271          12 : 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          24 :   struct TALER_RefundConfirmationPS rc = {
     281          12 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND),
     282          12 :     .purpose.size = htonl (sizeof (rc)),
     283             :     .h_contract_terms = *h_contract_terms,
     284             :     .coin_pub = *coin_pub,
     285             :     .merchant = *merchant,
     286          12 :     .rtransaction_id = GNUNET_htonll (rtransaction_id)
     287             :   };
     288             : 
     289          12 :   TALER_amount_hton (&rc.refund_amount,
     290             :                      refund_amount);
     291          12 :   if (GNUNET_OK !=
     292          12 :       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          12 :   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_EccSignaturePurpose 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          24 : 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          24 :   struct TALER_RefreshMeltConfirmationPS confirm = {
     345          24 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT),
     346          24 :     .purpose.size = htonl (sizeof (confirm)),
     347             :     .rc = *rc,
     348          24 :     .noreveal_index = htonl (noreveal_index)
     349             :   };
     350             : 
     351          24 :   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_EccSignaturePurpose 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_EccSignaturePurpose 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         896 : 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        1792 :   struct TALER_ExchangeKeySetPS ks = {
     554         896 :     .purpose.size = htonl (sizeof (ks)),
     555         896 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_KEY_SET),
     556         896 :     .list_issue_date = GNUNET_TIME_timestamp_hton (timestamp),
     557             :     .hc = *hc
     558             :   };
     559             : 
     560         896 :   return scb (cls,
     561             :               &ks.purpose,
     562             :               pub,
     563             :               sig);
     564             : }
     565             : 
     566             : 
     567             : enum GNUNET_GenericReturnValue
     568          42 : 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          84 :   struct TALER_ExchangeKeySetPS ks = {
     575          42 :     .purpose.size = htonl (sizeof (ks)),
     576          42 :     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_KEY_SET),
     577          42 :     .list_issue_date = GNUNET_TIME_timestamp_hton (timestamp),
     578             :     .hc = *hc
     579             :   };
     580             : 
     581             :   return
     582          42 :     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_EccSignaturePurpose 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_EccSignaturePurpose 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_EccSignaturePurpose 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_EccSignaturePurpose 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_EccSignaturePurpose 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_EccSignaturePurpose 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_EccSignaturePurpose 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_EccSignaturePurpose 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_EccSignaturePurpose 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_EccSignaturePurpose 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_EccSignaturePurpose 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_EccSignaturePurpose 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 1.16