LCOV - code coverage report
Current view: top level - util - offline_signatures.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 66.0 % 321 212
Test Date: 2026-04-14 15:39:31 Functions: 65.6 % 32 21

            Line data    Source code
       1              : /*
       2              :   This file is part of TALER
       3              :   Copyright (C) 2020-2024 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 offline_signatures.c
      18              :  * @brief Utility functions for Taler exchange offline signatures
      19              :  * @author Christian Grothoff
      20              :  */
      21              : #include "taler/taler_util.h"
      22              : #include "taler/taler_signatures.h"
      23              : 
      24              : 
      25              : GNUNET_NETWORK_STRUCT_BEGIN
      26              : 
      27              : /**
      28              :  * @brief Signature made by the exchange offline key over the information of
      29              :  * an AML officer status change.
      30              :  */
      31              : struct TALER_MasterAmlOfficerStatusPS
      32              : {
      33              : 
      34              :   /**
      35              :    * Purpose is #TALER_SIGNATURE_MASTER_AML_KEY.   Signed
      36              :    * by a `struct TALER_MasterPublicKeyP` using EdDSA.
      37              :    */
      38              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
      39              : 
      40              :   /**
      41              :    * Time of the change.
      42              :    */
      43              :   struct GNUNET_TIME_TimestampNBO change_date;
      44              : 
      45              :   /**
      46              :    * Public key of the AML officer.
      47              :    */
      48              :   struct TALER_AmlOfficerPublicKeyP officer_pub;
      49              : 
      50              :   /**
      51              :    * Hash over the AML officer's name.
      52              :    */
      53              :   struct GNUNET_HashCode h_officer_name GNUNET_PACKED;
      54              : 
      55              :   /**
      56              :    * Bitmask: 1 if enabled; 2 for read-only access. in NBO.
      57              :    */
      58              :   uint32_t is_active GNUNET_PACKED;
      59              : };
      60              : GNUNET_NETWORK_STRUCT_END
      61              : 
      62              : 
      63              : void
      64            4 : TALER_exchange_offline_aml_officer_status_sign (
      65              :   const struct TALER_AmlOfficerPublicKeyP *officer_pub,
      66              :   const char *officer_name,
      67              :   struct GNUNET_TIME_Timestamp change_date,
      68              :   bool is_active,
      69              :   bool read_only,
      70              :   const struct TALER_MasterPrivateKeyP *master_priv,
      71              :   struct TALER_MasterSignatureP *master_sig)
      72              : {
      73           12 :   struct TALER_MasterAmlOfficerStatusPS as = {
      74            4 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_AML_KEY),
      75            4 :     .purpose.size = htonl (sizeof (as)),
      76            4 :     .change_date = GNUNET_TIME_timestamp_hton (change_date),
      77              :     .officer_pub = *officer_pub,
      78            4 :     .is_active = htonl ((is_active ? 1 : 0) + (read_only ? 2 : 0))
      79              :   };
      80              : 
      81            4 :   GNUNET_CRYPTO_hash (officer_name,
      82            4 :                       strlen (officer_name) + 1,
      83              :                       &as.h_officer_name);
      84            4 :   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
      85              :                             &as,
      86              :                             &master_sig->eddsa_signature);
      87            4 : }
      88              : 
      89              : 
      90              : enum GNUNET_GenericReturnValue
      91            4 : TALER_exchange_offline_aml_officer_status_verify (
      92              :   const struct TALER_AmlOfficerPublicKeyP *officer_pub,
      93              :   const char *officer_name,
      94              :   struct GNUNET_TIME_Timestamp change_date,
      95              :   bool is_active,
      96              :   bool read_only,
      97              :   const struct TALER_MasterPublicKeyP *master_pub,
      98              :   const struct TALER_MasterSignatureP *master_sig)
      99              : {
     100           12 :   struct TALER_MasterAmlOfficerStatusPS as = {
     101            4 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_AML_KEY),
     102            4 :     .purpose.size = htonl (sizeof (as)),
     103            4 :     .change_date = GNUNET_TIME_timestamp_hton (change_date),
     104              :     .officer_pub = *officer_pub,
     105            4 :     .is_active = htonl ((is_active ? 1 : 0) + (read_only ? 2 : 0))
     106              :   };
     107              : 
     108            4 :   GNUNET_CRYPTO_hash (officer_name,
     109            4 :                       strlen (officer_name) + 1,
     110              :                       &as.h_officer_name);
     111            4 :   return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_AML_KEY,
     112              :                                      &as,
     113              :                                      &master_sig->eddsa_signature,
     114              :                                      &master_pub->eddsa_pub);
     115              : }
     116              : 
     117              : 
     118              : GNUNET_NETWORK_STRUCT_BEGIN
     119              : 
     120              : /**
     121              :  * @brief Signature made by the exchange offline key over the information of
     122              :  * an auditor to be added to the exchange's set of auditors.
     123              :  */
     124              : struct TALER_MasterAddAuditorPS
     125              : {
     126              : 
     127              :   /**
     128              :    * Purpose is #TALER_SIGNATURE_MASTER_ADD_AUDITOR.   Signed
     129              :    * by a `struct TALER_MasterPublicKeyP` using EdDSA.
     130              :    */
     131              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
     132              : 
     133              :   /**
     134              :    * Time of the change.
     135              :    */
     136              :   struct GNUNET_TIME_TimestampNBO start_date;
     137              : 
     138              :   /**
     139              :    * Public key of the auditor.
     140              :    */
     141              :   struct TALER_AuditorPublicKeyP auditor_pub;
     142              : 
     143              :   /**
     144              :    * Hash over the auditor's URL.
     145              :    */
     146              :   struct GNUNET_HashCode h_auditor_url GNUNET_PACKED;
     147              : };
     148              : GNUNET_NETWORK_STRUCT_END
     149              : 
     150              : 
     151              : void
     152            8 : TALER_exchange_offline_auditor_add_sign (
     153              :   const struct TALER_AuditorPublicKeyP *auditor_pub,
     154              :   const char *auditor_url,
     155              :   struct GNUNET_TIME_Timestamp start_date,
     156              :   const struct TALER_MasterPrivateKeyP *master_priv,
     157              :   struct TALER_MasterSignatureP *master_sig)
     158              : {
     159           16 :   struct TALER_MasterAddAuditorPS kv = {
     160            8 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_ADD_AUDITOR),
     161            8 :     .purpose.size = htonl (sizeof (kv)),
     162            8 :     .start_date = GNUNET_TIME_timestamp_hton (start_date),
     163              :     .auditor_pub = *auditor_pub,
     164              :   };
     165              : 
     166            8 :   GNUNET_CRYPTO_hash (auditor_url,
     167            8 :                       strlen (auditor_url) + 1,
     168              :                       &kv.h_auditor_url);
     169            8 :   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
     170              :                             &kv,
     171              :                             &master_sig->eddsa_signature);
     172            8 : }
     173              : 
     174              : 
     175              : enum GNUNET_GenericReturnValue
     176           10 : TALER_exchange_offline_auditor_add_verify (
     177              :   const struct TALER_AuditorPublicKeyP *auditor_pub,
     178              :   const char *auditor_url,
     179              :   struct GNUNET_TIME_Timestamp start_date,
     180              :   const struct TALER_MasterPublicKeyP *master_pub,
     181              :   const struct TALER_MasterSignatureP *master_sig)
     182              : {
     183           20 :   struct TALER_MasterAddAuditorPS aa = {
     184           10 :     .purpose.purpose = htonl (
     185              :       TALER_SIGNATURE_MASTER_ADD_AUDITOR),
     186           10 :     .purpose.size = htonl (sizeof (aa)),
     187           10 :     .start_date = GNUNET_TIME_timestamp_hton (start_date),
     188              :     .auditor_pub = *auditor_pub
     189              :   };
     190              : 
     191           10 :   GNUNET_CRYPTO_hash (auditor_url,
     192           10 :                       strlen (auditor_url) + 1,
     193              :                       &aa.h_auditor_url);
     194           10 :   return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_ADD_AUDITOR,
     195              :                                      &aa,
     196              :                                      &master_sig->eddsa_signature,
     197              :                                      &master_pub->eddsa_pub);
     198              : }
     199              : 
     200              : 
     201              : GNUNET_NETWORK_STRUCT_BEGIN
     202              : 
     203              : /**
     204              :  * @brief Signature made by the exchange offline key over the information of
     205              :  * an auditor to be removed from the exchange's set of auditors.
     206              :  */
     207              : struct TALER_MasterDelAuditorPS
     208              : {
     209              : 
     210              :   /**
     211              :    * Purpose is #TALER_SIGNATURE_MASTER_DEL_AUDITOR.   Signed
     212              :    * by a `struct TALER_MasterPublicKeyP` using EdDSA.
     213              :    */
     214              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
     215              : 
     216              :   /**
     217              :    * Time of the change.
     218              :    */
     219              :   struct GNUNET_TIME_TimestampNBO end_date;
     220              : 
     221              :   /**
     222              :    * Public key of the auditor.
     223              :    */
     224              :   struct TALER_AuditorPublicKeyP auditor_pub;
     225              : 
     226              : };
     227              : GNUNET_NETWORK_STRUCT_END
     228              : 
     229              : 
     230              : void
     231            6 : TALER_exchange_offline_auditor_del_sign (
     232              :   const struct TALER_AuditorPublicKeyP *auditor_pub,
     233              :   struct GNUNET_TIME_Timestamp end_date,
     234              :   const struct TALER_MasterPrivateKeyP *master_priv,
     235              :   struct TALER_MasterSignatureP *master_sig)
     236              : {
     237           12 :   struct TALER_MasterDelAuditorPS kv = {
     238            6 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_DEL_AUDITOR),
     239            6 :     .purpose.size = htonl (sizeof (kv)),
     240            6 :     .end_date = GNUNET_TIME_timestamp_hton (end_date),
     241              :     .auditor_pub = *auditor_pub,
     242              :   };
     243              : 
     244            6 :   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
     245              :                             &kv,
     246              :                             &master_sig->eddsa_signature);
     247            6 : }
     248              : 
     249              : 
     250              : enum GNUNET_GenericReturnValue
     251            8 : TALER_exchange_offline_auditor_del_verify (
     252              :   const struct TALER_AuditorPublicKeyP *auditor_pub,
     253              :   struct GNUNET_TIME_Timestamp end_date,
     254              :   const struct TALER_MasterPublicKeyP *master_pub,
     255              :   const struct TALER_MasterSignatureP *master_sig)
     256              : {
     257           16 :   struct TALER_MasterDelAuditorPS da = {
     258            8 :     .purpose.purpose = htonl (
     259              :       TALER_SIGNATURE_MASTER_DEL_AUDITOR),
     260            8 :     .purpose.size = htonl (sizeof (da)),
     261            8 :     .end_date = GNUNET_TIME_timestamp_hton (end_date),
     262              :     .auditor_pub = *auditor_pub
     263              :   };
     264              : 
     265            8 :   return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_DEL_AUDITOR,
     266              :                                      &da,
     267              :                                      &master_sig->eddsa_signature,
     268              :                                      &master_pub->eddsa_pub);
     269              : }
     270              : 
     271              : 
     272              : GNUNET_NETWORK_STRUCT_BEGIN
     273              : 
     274              : /**
     275              :  * @brief Message confirming that a denomination key was revoked.
     276              :  */
     277              : struct TALER_MasterDenominationKeyRevocationPS
     278              : {
     279              :   /**
     280              :    * Purpose is #TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED.
     281              :    */
     282              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
     283              : 
     284              :   /**
     285              :    * Hash of the denomination key.
     286              :    */
     287              :   struct TALER_DenominationHashP h_denom_pub;
     288              : 
     289              : };
     290              : 
     291              : GNUNET_NETWORK_STRUCT_END
     292              : 
     293              : 
     294              : void
     295            0 : TALER_exchange_offline_denomination_revoke_sign (
     296              :   const struct TALER_DenominationHashP *h_denom_pub,
     297              :   const struct TALER_MasterPrivateKeyP *master_priv,
     298              :   struct TALER_MasterSignatureP *master_sig)
     299              : {
     300            0 :   struct TALER_MasterDenominationKeyRevocationPS rm = {
     301            0 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED),
     302            0 :     .purpose.size = htonl (sizeof (rm)),
     303              :     .h_denom_pub = *h_denom_pub
     304              :   };
     305              : 
     306            0 :   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
     307              :                             &rm,
     308              :                             &master_sig->eddsa_signature);
     309            0 : }
     310              : 
     311              : 
     312              : enum GNUNET_GenericReturnValue
     313            0 : TALER_exchange_offline_denomination_revoke_verify (
     314              :   const struct TALER_DenominationHashP *h_denom_pub,
     315              :   const struct TALER_MasterPublicKeyP *master_pub,
     316              :   const struct TALER_MasterSignatureP *master_sig)
     317              : {
     318            0 :   struct TALER_MasterDenominationKeyRevocationPS kr = {
     319            0 :     .purpose.purpose = htonl (
     320              :       TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED),
     321            0 :     .purpose.size = htonl (sizeof (kr)),
     322              :     .h_denom_pub = *h_denom_pub
     323              :   };
     324              : 
     325            0 :   return GNUNET_CRYPTO_eddsa_verify (
     326              :     TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED,
     327              :     &kr,
     328              :     &master_sig->eddsa_signature,
     329              :     &master_pub->eddsa_pub);
     330              : }
     331              : 
     332              : 
     333              : GNUNET_NETWORK_STRUCT_BEGIN
     334              : 
     335              : /**
     336              :  * @brief Message confirming that an exchange online signing key was revoked.
     337              :  */
     338              : struct TALER_MasterSigningKeyRevocationPS
     339              : {
     340              :   /**
     341              :    * Purpose is #TALER_SIGNATURE_MASTER_SIGNING_KEY_REVOKED.
     342              :    */
     343              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
     344              : 
     345              :   /**
     346              :    * The exchange's public key.
     347              :    */
     348              :   struct TALER_ExchangePublicKeyP exchange_pub;
     349              : 
     350              : };
     351              : 
     352              : GNUNET_NETWORK_STRUCT_END
     353              : 
     354              : 
     355              : void
     356            0 : TALER_exchange_offline_signkey_revoke_sign (
     357              :   const struct TALER_ExchangePublicKeyP *exchange_pub,
     358              :   const struct TALER_MasterPrivateKeyP *master_priv,
     359              :   struct TALER_MasterSignatureP *master_sig)
     360              : {
     361            0 :   struct TALER_MasterSigningKeyRevocationPS kv = {
     362            0 :     .purpose.purpose = htonl (
     363              :       TALER_SIGNATURE_MASTER_SIGNING_KEY_REVOKED),
     364            0 :     .purpose.size = htonl (sizeof (kv)),
     365              :     .exchange_pub = *exchange_pub
     366              :   };
     367              : 
     368            0 :   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
     369              :                             &kv,
     370              :                             &master_sig->eddsa_signature);
     371            0 : }
     372              : 
     373              : 
     374              : enum GNUNET_GenericReturnValue
     375            0 : TALER_exchange_offline_signkey_revoke_verify (
     376              :   const struct TALER_ExchangePublicKeyP *exchange_pub,
     377              :   const struct TALER_MasterPublicKeyP *master_pub,
     378              :   const struct TALER_MasterSignatureP *master_sig)
     379              : {
     380            0 :   struct TALER_MasterSigningKeyRevocationPS rm = {
     381            0 :     .purpose.purpose = htonl (
     382              :       TALER_SIGNATURE_MASTER_SIGNING_KEY_REVOKED),
     383            0 :     .purpose.size = htonl (sizeof (rm)),
     384              :     .exchange_pub = *exchange_pub
     385              :   };
     386              : 
     387            0 :   return GNUNET_CRYPTO_eddsa_verify (
     388              :     TALER_SIGNATURE_MASTER_SIGNING_KEY_REVOKED,
     389              :     &rm,
     390              :     &master_sig->eddsa_signature,
     391              :     &master_pub->eddsa_pub);
     392              : }
     393              : 
     394              : 
     395              : GNUNET_NETWORK_STRUCT_BEGIN
     396              : 
     397              : /**
     398              :  * @brief Information about a signing key of the exchange.  Signing keys are used
     399              :  * to sign exchange messages other than coins, i.e. to confirm that a
     400              :  * deposit was successful or that a refresh was accepted.
     401              :  */
     402              : struct TALER_ExchangeSigningKeyValidityPS
     403              : {
     404              : 
     405              :   /**
     406              :    * Purpose is #TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY.
     407              :    */
     408              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
     409              : 
     410              :   /**
     411              :    * When does this signing key begin to be valid?
     412              :    */
     413              :   struct GNUNET_TIME_TimestampNBO start;
     414              : 
     415              :   /**
     416              :    * When does this signing key expire? Note: This is currently when
     417              :    * the Exchange will definitively stop using it.  Signatures made with
     418              :    * the key remain valid until @e end.  When checking validity periods,
     419              :    * clients should allow for some overlap between keys and tolerate
     420              :    * the use of either key during the overlap time (due to the
     421              :    * possibility of clock skew).
     422              :    */
     423              :   struct GNUNET_TIME_TimestampNBO expire;
     424              : 
     425              :   /**
     426              :    * When do signatures with this signing key become invalid?  After
     427              :    * this point, these signatures cannot be used in (legal) disputes
     428              :    * anymore, as the Exchange is then allowed to destroy its side of the
     429              :    * evidence.  @e end is expected to be significantly larger than @e
     430              :    * expire (by a year or more).
     431              :    */
     432              :   struct GNUNET_TIME_TimestampNBO end;
     433              : 
     434              :   /**
     435              :    * The public online signing key that the exchange will use
     436              :    * between @e start and @e expire.
     437              :    */
     438              :   struct TALER_ExchangePublicKeyP signkey_pub;
     439              : };
     440              : 
     441              : GNUNET_NETWORK_STRUCT_END
     442              : 
     443              : 
     444              : void
     445           21 : TALER_exchange_offline_signkey_validity_sign (
     446              :   const struct TALER_ExchangePublicKeyP *exchange_pub,
     447              :   struct GNUNET_TIME_Timestamp start_sign,
     448              :   struct GNUNET_TIME_Timestamp end_sign,
     449              :   struct GNUNET_TIME_Timestamp end_legal,
     450              :   const struct TALER_MasterPrivateKeyP *master_priv,
     451              :   struct TALER_MasterSignatureP *master_sig)
     452              : {
     453           42 :   struct TALER_ExchangeSigningKeyValidityPS skv = {
     454           21 :     .purpose.purpose = htonl (
     455              :       TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY),
     456           21 :     .purpose.size = htonl (sizeof (skv)),
     457           21 :     .start = GNUNET_TIME_timestamp_hton (start_sign),
     458           21 :     .expire = GNUNET_TIME_timestamp_hton (end_sign),
     459           21 :     .end = GNUNET_TIME_timestamp_hton (end_legal),
     460              :     .signkey_pub = *exchange_pub
     461              :   };
     462              : 
     463           21 :   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
     464              :                             &skv,
     465              :                             &master_sig->eddsa_signature);
     466           21 : }
     467              : 
     468              : 
     469              : enum GNUNET_GenericReturnValue
     470           89 : TALER_exchange_offline_signkey_validity_verify (
     471              :   const struct TALER_ExchangePublicKeyP *exchange_pub,
     472              :   struct GNUNET_TIME_Timestamp start_sign,
     473              :   struct GNUNET_TIME_Timestamp end_sign,
     474              :   struct GNUNET_TIME_Timestamp end_legal,
     475              :   const struct TALER_MasterPublicKeyP *master_pub,
     476              :   const struct TALER_MasterSignatureP *master_sig)
     477              : {
     478          178 :   struct TALER_ExchangeSigningKeyValidityPS skv = {
     479           89 :     .purpose.purpose = htonl (
     480              :       TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY),
     481           89 :     .purpose.size = htonl (sizeof (skv)),
     482           89 :     .start = GNUNET_TIME_timestamp_hton (start_sign),
     483           89 :     .expire = GNUNET_TIME_timestamp_hton (end_sign),
     484           89 :     .end = GNUNET_TIME_timestamp_hton (end_legal),
     485              :     .signkey_pub = *exchange_pub
     486              :   };
     487              : 
     488              :   return
     489           89 :     GNUNET_CRYPTO_eddsa_verify (
     490              :     TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY,
     491              :     &skv,
     492              :     &master_sig->eddsa_signature,
     493              :     &master_pub->eddsa_pub);
     494              : }
     495              : 
     496              : 
     497              : GNUNET_NETWORK_STRUCT_BEGIN
     498              : 
     499              : /**
     500              :  * @brief Information about a denomination key. Denomination keys
     501              :  * are used to sign coins of a certain value into existence.
     502              :  */
     503              : struct TALER_DenominationKeyValidityPS
     504              : {
     505              : 
     506              :   /**
     507              :    * Purpose is #TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY.
     508              :    */
     509              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
     510              : 
     511              :   /**
     512              :    * The long-term offline master key of the exchange that was
     513              :    * used to create @e signature.
     514              :    *
     515              :    * Note: This member is not strictly required, but here for
     516              :    * backwards-compatibility. If we ever again badly break
     517              :    * compatibility, we might want to remove it.
     518              :    */
     519              :   struct TALER_MasterPublicKeyP master;
     520              : 
     521              :   /**
     522              :    * Start time of the validity period for this key.
     523              :    */
     524              :   struct GNUNET_TIME_TimestampNBO start;
     525              : 
     526              :   /**
     527              :    * The exchange will sign fresh coins between @e start and this time.
     528              :    * @e expire_withdraw will be somewhat larger than @e start to
     529              :    * ensure a sufficiently large anonymity set, while also allowing
     530              :    * the Exchange to limit the financial damage in case of a key being
     531              :    * compromised.  Thus, exchanges with low volume are expected to have a
     532              :    * longer withdraw period (@e expire_withdraw - @e start) than exchanges
     533              :    * with high transaction volume.  The period may also differ between
     534              :    * types of coins.  A exchange may also have a few denomination keys
     535              :    * with the same value with overlapping validity periods, to address
     536              :    * issues such as clock skew.
     537              :    */
     538              :   struct GNUNET_TIME_TimestampNBO expire_withdraw;
     539              : 
     540              :   /**
     541              :    * Coins signed with the denomination key must be spent or refreshed
     542              :    * between @e start and this expiration time.  After this time, the
     543              :    * exchange will refuse transactions involving this key as it will
     544              :    * "drop" the table with double-spending information (shortly after)
     545              :    * this time.  Note that wallets should refresh coins significantly
     546              :    * before this time to be on the safe side.  @e expire_deposit must be
     547              :    * significantly larger than @e expire_withdraw (by months or even
     548              :    * years).
     549              :    */
     550              :   struct GNUNET_TIME_TimestampNBO expire_deposit;
     551              : 
     552              :   /**
     553              :    * When do signatures with this denomination key become invalid?
     554              :    * After this point, these signatures cannot be used in (legal)
     555              :    * disputes anymore, as the Exchange is then allowed to destroy its side
     556              :    * of the evidence.  @e expire_legal is expected to be significantly
     557              :    * larger than @e expire_deposit (by a year or more).
     558              :    */
     559              :   struct GNUNET_TIME_TimestampNBO expire_legal;
     560              : 
     561              :   /**
     562              :    * The value of the coins signed with this denomination key.
     563              :    */
     564              :   struct TALER_AmountNBO value;
     565              : 
     566              :   /**
     567              :    * Fees for the coin.
     568              :    */
     569              :   struct TALER_DenomFeeSetNBOP fees;
     570              : 
     571              :   /**
     572              :    * Hash code of the denomination public key. (Used to avoid having
     573              :    * the variable-size RSA key in this struct.)
     574              :    */
     575              :   struct TALER_DenominationHashP denom_hash GNUNET_PACKED;
     576              : 
     577              : };
     578              : 
     579              : GNUNET_NETWORK_STRUCT_END
     580              : 
     581              : 
     582              : void
     583          469 : TALER_exchange_offline_denom_validity_sign (
     584              :   const struct TALER_DenominationHashP *h_denom_pub,
     585              :   struct GNUNET_TIME_Timestamp stamp_start,
     586              :   struct GNUNET_TIME_Timestamp stamp_expire_withdraw,
     587              :   struct GNUNET_TIME_Timestamp stamp_expire_deposit,
     588              :   struct GNUNET_TIME_Timestamp stamp_expire_legal,
     589              :   const struct TALER_Amount *coin_value,
     590              :   const struct TALER_DenomFeeSet *fees,
     591              :   const struct TALER_MasterPrivateKeyP *master_priv,
     592              :   struct TALER_MasterSignatureP *master_sig)
     593              : {
     594          938 :   struct TALER_DenominationKeyValidityPS issue = {
     595              :     .purpose.purpose
     596          469 :       = htonl (TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY),
     597              :     .purpose.size
     598          469 :       = htonl (sizeof (issue)),
     599          469 :     .start = GNUNET_TIME_timestamp_hton (stamp_start),
     600          469 :     .expire_withdraw = GNUNET_TIME_timestamp_hton (stamp_expire_withdraw),
     601          469 :     .expire_deposit = GNUNET_TIME_timestamp_hton (stamp_expire_deposit),
     602          469 :     .expire_legal = GNUNET_TIME_timestamp_hton (stamp_expire_legal),
     603              :     .denom_hash = *h_denom_pub
     604              :   };
     605              : 
     606          469 :   GNUNET_CRYPTO_eddsa_key_get_public (&master_priv->eddsa_priv,
     607              :                                       &issue.master.eddsa_pub);
     608          469 :   TALER_amount_hton (&issue.value,
     609              :                      coin_value);
     610          469 :   TALER_denom_fee_set_hton (&issue.fees,
     611              :                             fees);
     612          469 :   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
     613              :                             &issue,
     614              :                             &master_sig->eddsa_signature);
     615          469 : }
     616              : 
     617              : 
     618              : enum GNUNET_GenericReturnValue
     619         2170 : TALER_exchange_offline_denom_validity_verify (
     620              :   const struct TALER_DenominationHashP *h_denom_pub,
     621              :   struct GNUNET_TIME_Timestamp stamp_start,
     622              :   struct GNUNET_TIME_Timestamp stamp_expire_withdraw,
     623              :   struct GNUNET_TIME_Timestamp stamp_expire_deposit,
     624              :   struct GNUNET_TIME_Timestamp stamp_expire_legal,
     625              :   const struct TALER_Amount *coin_value,
     626              :   const struct TALER_DenomFeeSet *fees,
     627              :   const struct TALER_MasterPublicKeyP *master_pub,
     628              :   const struct TALER_MasterSignatureP *master_sig)
     629              : {
     630         4340 :   struct TALER_DenominationKeyValidityPS dkv = {
     631         2170 :     .purpose.purpose = htonl (
     632              :       TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY),
     633         2170 :     .purpose.size = htonl (sizeof (dkv)),
     634              :     .master = *master_pub,
     635         2170 :     .start = GNUNET_TIME_timestamp_hton (stamp_start),
     636         2170 :     .expire_withdraw = GNUNET_TIME_timestamp_hton (stamp_expire_withdraw),
     637         2170 :     .expire_deposit = GNUNET_TIME_timestamp_hton (stamp_expire_deposit),
     638         2170 :     .expire_legal = GNUNET_TIME_timestamp_hton (stamp_expire_legal),
     639              :     .denom_hash = *h_denom_pub
     640              :   };
     641              : 
     642         2170 :   TALER_amount_hton (&dkv.value,
     643              :                      coin_value);
     644         2170 :   TALER_denom_fee_set_hton (&dkv.fees,
     645              :                             fees);
     646              :   return
     647         2170 :     GNUNET_CRYPTO_eddsa_verify (
     648              :     TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY,
     649              :     &dkv,
     650              :     &master_sig->eddsa_signature,
     651              :     &master_pub->eddsa_pub);
     652              : }
     653              : 
     654              : 
     655              : GNUNET_NETWORK_STRUCT_BEGIN
     656              : 
     657              : /**
     658              :  * @brief Signature made by the exchange offline key over the information of
     659              :  * a payto:// URI to be added to the exchange's set of active wire accounts.
     660              :  */
     661              : struct TALER_MasterAddWirePS
     662              : {
     663              : 
     664              :   /**
     665              :    * Purpose is #TALER_SIGNATURE_MASTER_ADD_WIRE.   Signed
     666              :    * by a `struct TALER_MasterPublicKeyP` using EdDSA.
     667              :    */
     668              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
     669              : 
     670              :   /**
     671              :    * Time of the change.
     672              :    */
     673              :   struct GNUNET_TIME_TimestampNBO start_date;
     674              : 
     675              :   /**
     676              :    * Hash over the exchange's payto URI.
     677              :    */
     678              :   struct TALER_FullPaytoHashP h_payto GNUNET_PACKED;
     679              : 
     680              :   /**
     681              :    * Hash over the conversion URL, all zeros if there
     682              :    * is no conversion URL.
     683              :    */
     684              :   struct GNUNET_HashCode h_conversion_url;
     685              : 
     686              :   /**
     687              :    * Hash over the open banking gateway URL, all zeros if there
     688              :    * is no open banking gateway URL.
     689              :    */
     690              :   struct GNUNET_HashCode h_open_banking_gateway;
     691              : 
     692              :   /**
     693              :    * Hash over the wire transfer gateway URL, all zeros if there
     694              :    * is no wire transfer gateway URL.
     695              :    */
     696              :   struct GNUNET_HashCode h_wire_transfer_gateway;
     697              : 
     698              :   /**
     699              :    * Hash over the debit restrictions.
     700              :    */
     701              :   struct GNUNET_HashCode h_debit_restrictions;
     702              : 
     703              :   /**
     704              :    * Hash over the credit restrictions.
     705              :    */
     706              :   struct GNUNET_HashCode h_credit_restrictions;
     707              : 
     708              : };
     709              : 
     710              : 
     711              : /**
     712              :  * @brief Signature made by the exchange offline key over the information of
     713              :  * a payto:// URI to be added to the exchange's set of active wire accounts.
     714              :  *
     715              :  * Legacy pre-v33 protocol version.
     716              :  */
     717              : struct TALER_MasterAddWire32PS
     718              : {
     719              : 
     720              :   /**
     721              :    * Purpose is #TALER_SIGNATURE_MASTER_ADD_WIRE.   Signed
     722              :    * by a `struct TALER_MasterPublicKeyP` using EdDSA.
     723              :    */
     724              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
     725              : 
     726              :   /**
     727              :    * Time of the change.
     728              :    */
     729              :   struct GNUNET_TIME_TimestampNBO start_date;
     730              : 
     731              :   /**
     732              :    * Hash over the exchange's payto URI.
     733              :    */
     734              :   struct TALER_FullPaytoHashP h_payto GNUNET_PACKED;
     735              : 
     736              :   /**
     737              :    * Hash over the conversion URL, all zeros if there
     738              :    * is no conversion URL.
     739              :    */
     740              :   struct GNUNET_HashCode h_conversion_url;
     741              : 
     742              :   /**
     743              :    * Hash over the debit restrictions.
     744              :    */
     745              :   struct GNUNET_HashCode h_debit_restrictions;
     746              : 
     747              :   /**
     748              :    * Hash over the credit restrictions.
     749              :    */
     750              :   struct GNUNET_HashCode h_credit_restrictions;
     751              : 
     752              : };
     753              : 
     754              : GNUNET_NETWORK_STRUCT_END
     755              : 
     756              : 
     757              : void
     758           23 : TALER_exchange_offline_wire_add_sign (
     759              :   const struct TALER_FullPayto payto_uri,
     760              :   const char *conversion_url,
     761              :   const char *open_banking_gateway,
     762              :   const char *wire_transfer_gateway,
     763              :   const json_t *debit_restrictions,
     764              :   const json_t *credit_restrictions,
     765              :   struct GNUNET_TIME_Timestamp now,
     766              :   const struct TALER_MasterPrivateKeyP *master_priv,
     767              :   struct TALER_MasterSignatureP *master_sig)
     768              : {
     769           23 :   struct TALER_MasterAddWirePS kv = {
     770           23 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_ADD_WIRE),
     771           23 :     .purpose.size = htonl (sizeof (kv)),
     772           23 :     .start_date = GNUNET_TIME_timestamp_hton (now),
     773              :   };
     774              : 
     775           23 :   TALER_full_payto_hash (payto_uri,
     776              :                          &kv.h_payto);
     777           23 :   if (NULL != conversion_url)
     778            0 :     GNUNET_CRYPTO_hash (conversion_url,
     779            0 :                         strlen (conversion_url) + 1,
     780              :                         &kv.h_conversion_url);
     781           23 :   if (NULL != open_banking_gateway)
     782            0 :     GNUNET_CRYPTO_hash (open_banking_gateway,
     783            0 :                         strlen (open_banking_gateway) + 1,
     784              :                         &kv.h_open_banking_gateway);
     785           23 :   if (NULL != wire_transfer_gateway)
     786            0 :     GNUNET_CRYPTO_hash (wire_transfer_gateway,
     787            0 :                         strlen (wire_transfer_gateway) + 1,
     788              :                         &kv.h_wire_transfer_gateway);
     789           23 :   TALER_json_hash (debit_restrictions,
     790              :                    &kv.h_debit_restrictions);
     791           23 :   TALER_json_hash (credit_restrictions,
     792              :                    &kv.h_credit_restrictions);
     793           23 :   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
     794              :                             &kv,
     795              :                             &master_sig->eddsa_signature);
     796           23 : }
     797              : 
     798              : 
     799              : enum GNUNET_GenericReturnValue
     800           25 : TALER_exchange_offline_wire_add_verify (
     801              :   const struct TALER_FullPayto payto_uri,
     802              :   const char *conversion_url,
     803              :   const char *open_banking_gateway,
     804              :   const char *wire_transfer_gateway,
     805              :   const json_t *debit_restrictions,
     806              :   const json_t *credit_restrictions,
     807              :   struct GNUNET_TIME_Timestamp sign_time,
     808              :   const struct TALER_MasterPublicKeyP *master_pub,
     809              :   const struct TALER_MasterSignatureP *master_sig)
     810              : {
     811           25 :   struct TALER_MasterAddWirePS aw = {
     812           25 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_ADD_WIRE),
     813           25 :     .purpose.size = htonl (sizeof (aw)),
     814           25 :     .start_date = GNUNET_TIME_timestamp_hton (sign_time),
     815              :   };
     816              : 
     817           25 :   TALER_full_payto_hash (payto_uri,
     818              :                          &aw.h_payto);
     819           25 :   if (NULL != conversion_url)
     820            0 :     GNUNET_CRYPTO_hash (conversion_url,
     821            0 :                         strlen (conversion_url) + 1,
     822              :                         &aw.h_conversion_url);
     823           25 :   if (NULL != open_banking_gateway)
     824            0 :     GNUNET_CRYPTO_hash (open_banking_gateway,
     825            0 :                         strlen (open_banking_gateway) + 1,
     826              :                         &aw.h_open_banking_gateway);
     827           25 :   if (NULL != wire_transfer_gateway)
     828            0 :     GNUNET_CRYPTO_hash (wire_transfer_gateway,
     829            0 :                         strlen (wire_transfer_gateway) + 1,
     830              :                         &aw.h_wire_transfer_gateway);
     831           25 :   TALER_json_hash (debit_restrictions,
     832              :                    &aw.h_debit_restrictions);
     833           25 :   TALER_json_hash (credit_restrictions,
     834              :                    &aw.h_credit_restrictions);
     835              :   return
     836           25 :     GNUNET_CRYPTO_eddsa_verify (
     837              :     TALER_SIGNATURE_MASTER_ADD_WIRE,
     838              :     &aw,
     839              :     &master_sig->eddsa_signature,
     840              :     &master_pub->eddsa_pub);
     841              : }
     842              : 
     843              : 
     844              : enum GNUNET_GenericReturnValue
     845            0 : TALER_exchange_offline_wire_add_verify_32 (
     846              :   const struct TALER_FullPayto payto_uri,
     847              :   const char *conversion_url,
     848              :   const json_t *debit_restrictions,
     849              :   const json_t *credit_restrictions,
     850              :   struct GNUNET_TIME_Timestamp sign_time,
     851              :   const struct TALER_MasterPublicKeyP *master_pub,
     852              :   const struct TALER_MasterSignatureP *master_sig)
     853              : {
     854            0 :   struct TALER_MasterAddWire32PS aw = {
     855            0 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_ADD_WIRE),
     856            0 :     .purpose.size = htonl (sizeof (aw)),
     857            0 :     .start_date = GNUNET_TIME_timestamp_hton (sign_time),
     858              :   };
     859              : 
     860            0 :   TALER_full_payto_hash (payto_uri,
     861              :                          &aw.h_payto);
     862            0 :   if (NULL != conversion_url)
     863            0 :     GNUNET_CRYPTO_hash (conversion_url,
     864            0 :                         strlen (conversion_url) + 1,
     865              :                         &aw.h_conversion_url);
     866            0 :   TALER_json_hash (debit_restrictions,
     867              :                    &aw.h_debit_restrictions);
     868            0 :   TALER_json_hash (credit_restrictions,
     869              :                    &aw.h_credit_restrictions);
     870              :   return
     871            0 :     GNUNET_CRYPTO_eddsa_verify (
     872              :     TALER_SIGNATURE_MASTER_ADD_WIRE,
     873              :     &aw,
     874              :     &master_sig->eddsa_signature,
     875              :     &master_pub->eddsa_pub);
     876              : }
     877              : 
     878              : 
     879              : GNUNET_NETWORK_STRUCT_BEGIN
     880              : 
     881              : /**
     882              :  * @brief Signature made by the exchange offline key over the information of
     883              :  * a  wire method to be removed to the exchange's set of active accounts.
     884              :  */
     885              : struct TALER_MasterDelWirePS
     886              : {
     887              : 
     888              :   /**
     889              :    * Purpose is #TALER_SIGNATURE_MASTER_DEL_WIRE.   Signed
     890              :    * by a `struct TALER_MasterPublicKeyP` using EdDSA.
     891              :    */
     892              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
     893              : 
     894              :   /**
     895              :    * Time of the change.
     896              :    */
     897              :   struct GNUNET_TIME_TimestampNBO end_date;
     898              : 
     899              :   /**
     900              :    * Hash over the exchange's payto URI.
     901              :    */
     902              :   struct TALER_FullPaytoHashP h_payto GNUNET_PACKED;
     903              : 
     904              : };
     905              : 
     906              : GNUNET_NETWORK_STRUCT_END
     907              : 
     908              : 
     909              : void
     910            4 : TALER_exchange_offline_wire_del_sign (
     911              :   const struct TALER_FullPayto payto_uri,
     912              :   struct GNUNET_TIME_Timestamp now,
     913              :   const struct TALER_MasterPrivateKeyP *master_priv,
     914              :   struct TALER_MasterSignatureP *master_sig)
     915              : {
     916            4 :   struct TALER_MasterDelWirePS kv = {
     917            4 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_DEL_WIRE),
     918            4 :     .purpose.size = htonl (sizeof (kv)),
     919            4 :     .end_date = GNUNET_TIME_timestamp_hton (now),
     920              :   };
     921              : 
     922            4 :   TALER_full_payto_hash (payto_uri,
     923              :                          &kv.h_payto);
     924            4 :   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
     925              :                             &kv,
     926              :                             &master_sig->eddsa_signature);
     927            4 : }
     928              : 
     929              : 
     930              : enum GNUNET_GenericReturnValue
     931            6 : TALER_exchange_offline_wire_del_verify (
     932              :   const struct TALER_FullPayto payto_uri,
     933              :   struct GNUNET_TIME_Timestamp sign_time,
     934              :   const struct TALER_MasterPublicKeyP *master_pub,
     935              :   const struct TALER_MasterSignatureP *master_sig)
     936              : {
     937            6 :   struct TALER_MasterDelWirePS aw = {
     938            6 :     .purpose.purpose = htonl (
     939              :       TALER_SIGNATURE_MASTER_DEL_WIRE),
     940            6 :     .purpose.size = htonl (sizeof (aw)),
     941            6 :     .end_date = GNUNET_TIME_timestamp_hton (sign_time),
     942              :   };
     943              : 
     944            6 :   TALER_full_payto_hash (payto_uri,
     945              :                          &aw.h_payto);
     946            6 :   return GNUNET_CRYPTO_eddsa_verify (
     947              :     TALER_SIGNATURE_MASTER_DEL_WIRE,
     948              :     &aw,
     949              :     &master_sig->eddsa_signature,
     950              :     &master_pub->eddsa_pub);
     951              : }
     952              : 
     953              : 
     954              : GNUNET_NETWORK_STRUCT_BEGIN
     955              : 
     956              : /**
     957              :  * @brief Information signed by the exchange's master
     958              :  * key stating the wire fee to be paid per wire transfer.
     959              :  */
     960              : struct TALER_MasterWireFeePS
     961              : {
     962              : 
     963              :   /**
     964              :    * Purpose is #TALER_SIGNATURE_MASTER_WIRE_FEES.
     965              :    */
     966              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
     967              : 
     968              :   /**
     969              :    * Hash over the wire method (yes, H("x-taler-bank") or H("iban")), in lower
     970              :    * case, including 0-terminator.  Used to uniquely identify which
     971              :    * wire method these fees apply to.
     972              :    */
     973              :   struct GNUNET_HashCode h_wire_method;
     974              : 
     975              :   /**
     976              :    * Start date when the fee goes into effect.
     977              :    */
     978              :   struct GNUNET_TIME_TimestampNBO start_date;
     979              : 
     980              :   /**
     981              :    * End date when the fee stops being in effect (exclusive)
     982              :    */
     983              :   struct GNUNET_TIME_TimestampNBO end_date;
     984              : 
     985              :   /**
     986              :    * Fees charged for wire transfers using the
     987              :    * given wire method.
     988              :    */
     989              :   struct TALER_WireFeeSetNBOP fees;
     990              : 
     991              : };
     992              : 
     993              : GNUNET_NETWORK_STRUCT_END
     994              : 
     995              : 
     996              : void
     997           42 : TALER_exchange_offline_wire_fee_sign (
     998              :   const char *payment_method,
     999              :   struct GNUNET_TIME_Timestamp start_time,
    1000              :   struct GNUNET_TIME_Timestamp end_time,
    1001              :   const struct TALER_WireFeeSet *fees,
    1002              :   const struct TALER_MasterPrivateKeyP *master_priv,
    1003              :   struct TALER_MasterSignatureP *master_sig)
    1004              : {
    1005           42 :   struct TALER_MasterWireFeePS kv = {
    1006           42 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_WIRE_FEES),
    1007           42 :     .purpose.size = htonl (sizeof (kv)),
    1008           42 :     .start_date = GNUNET_TIME_timestamp_hton (start_time),
    1009           42 :     .end_date = GNUNET_TIME_timestamp_hton (end_time),
    1010              :   };
    1011              : 
    1012           42 :   GNUNET_CRYPTO_hash (payment_method,
    1013           42 :                       strlen (payment_method) + 1,
    1014              :                       &kv.h_wire_method);
    1015           42 :   TALER_wire_fee_set_hton (&kv.fees,
    1016              :                            fees);
    1017           42 :   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
    1018              :                             &kv,
    1019              :                             &master_sig->eddsa_signature);
    1020           42 : }
    1021              : 
    1022              : 
    1023              : enum GNUNET_GenericReturnValue
    1024          166 : TALER_exchange_offline_wire_fee_verify (
    1025              :   const char *payment_method,
    1026              :   struct GNUNET_TIME_Timestamp start_time,
    1027              :   struct GNUNET_TIME_Timestamp end_time,
    1028              :   const struct TALER_WireFeeSet *fees,
    1029              :   const struct TALER_MasterPublicKeyP *master_pub,
    1030              :   const struct TALER_MasterSignatureP *master_sig)
    1031              : {
    1032          166 :   struct TALER_MasterWireFeePS wf = {
    1033          166 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_WIRE_FEES),
    1034          166 :     .purpose.size = htonl (sizeof (wf)),
    1035          166 :     .start_date = GNUNET_TIME_timestamp_hton (start_time),
    1036          166 :     .end_date = GNUNET_TIME_timestamp_hton (end_time)
    1037              :   };
    1038              : 
    1039          166 :   GNUNET_CRYPTO_hash (payment_method,
    1040          166 :                       strlen (payment_method) + 1,
    1041              :                       &wf.h_wire_method);
    1042          166 :   TALER_wire_fee_set_hton (&wf.fees,
    1043              :                            fees);
    1044              :   return
    1045          166 :     GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_WIRE_FEES,
    1046              :                                 &wf,
    1047              :                                 &master_sig->eddsa_signature,
    1048              :                                 &master_pub->eddsa_pub);
    1049              : }
    1050              : 
    1051              : 
    1052              : GNUNET_NETWORK_STRUCT_BEGIN
    1053              : 
    1054              : /**
    1055              :  * Global fees charged by the exchange independent of
    1056              :  * denomination or wire method.
    1057              :  */
    1058              : struct TALER_MasterGlobalFeePS
    1059              : {
    1060              : 
    1061              :   /**
    1062              :    * Purpose is #TALER_SIGNATURE_MASTER_GLOBAL_FEES.
    1063              :    */
    1064              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    1065              : 
    1066              :   /**
    1067              :    * Start date when the fee goes into effect.
    1068              :    */
    1069              :   struct GNUNET_TIME_TimestampNBO start_date;
    1070              : 
    1071              :   /**
    1072              :    * End date when the fee stops being in effect (exclusive)
    1073              :    */
    1074              :   struct GNUNET_TIME_TimestampNBO end_date;
    1075              : 
    1076              :   /**
    1077              :    * How long does an exchange keep a purse around after a purse
    1078              :    * has expired (or been successfully merged)?  A 'GET' request
    1079              :    * for a purse will succeed until the purse expiration time
    1080              :    * plus this value.
    1081              :    */
    1082              :   struct GNUNET_TIME_RelativeNBO purse_timeout;
    1083              : 
    1084              :   /**
    1085              :    * How long will the exchange preserve the account history?  After an
    1086              :    * account was deleted/closed, the exchange will retain the account history
    1087              :    * for legal reasons until this time.
    1088              :    */
    1089              :   struct GNUNET_TIME_RelativeNBO history_expiration;
    1090              : 
    1091              :   /**
    1092              :    * Fee charged to the merchant per wire transfer.
    1093              :    */
    1094              :   struct TALER_GlobalFeeSetNBOP fees;
    1095              : 
    1096              :   /**
    1097              :    * Number of concurrent purses that any
    1098              :    * account holder is allowed to create without having
    1099              :    * to pay the @e purse_fee. Here given in NBO.
    1100              :    */
    1101              :   uint32_t purse_account_limit;
    1102              : 
    1103              : };
    1104              : 
    1105              : GNUNET_NETWORK_STRUCT_END
    1106              : 
    1107              : 
    1108              : void
    1109           34 : TALER_exchange_offline_global_fee_sign (
    1110              :   struct GNUNET_TIME_Timestamp start_time,
    1111              :   struct GNUNET_TIME_Timestamp end_time,
    1112              :   const struct TALER_GlobalFeeSet *fees,
    1113              :   struct GNUNET_TIME_Relative purse_timeout,
    1114              :   struct GNUNET_TIME_Relative history_expiration,
    1115              :   uint32_t purse_account_limit,
    1116              :   const struct TALER_MasterPrivateKeyP *master_priv,
    1117              :   struct TALER_MasterSignatureP *master_sig)
    1118              : {
    1119           68 :   struct TALER_MasterGlobalFeePS wf = {
    1120           34 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_GLOBAL_FEES),
    1121           34 :     .purpose.size = htonl (sizeof (wf)),
    1122           34 :     .start_date = GNUNET_TIME_timestamp_hton (start_time),
    1123           34 :     .end_date = GNUNET_TIME_timestamp_hton (end_time),
    1124           34 :     .purse_timeout = GNUNET_TIME_relative_hton (purse_timeout),
    1125           34 :     .history_expiration = GNUNET_TIME_relative_hton (history_expiration),
    1126           34 :     .purse_account_limit = htonl (purse_account_limit)
    1127              :   };
    1128              : 
    1129           34 :   TALER_global_fee_set_hton (&wf.fees,
    1130              :                              fees);
    1131           34 :   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
    1132              :                             &wf,
    1133              :                             &master_sig->eddsa_signature);
    1134           34 : }
    1135              : 
    1136              : 
    1137              : enum GNUNET_GenericReturnValue
    1138          148 : TALER_exchange_offline_global_fee_verify (
    1139              :   struct GNUNET_TIME_Timestamp start_time,
    1140              :   struct GNUNET_TIME_Timestamp end_time,
    1141              :   const struct TALER_GlobalFeeSet *fees,
    1142              :   struct GNUNET_TIME_Relative purse_timeout,
    1143              :   struct GNUNET_TIME_Relative history_expiration,
    1144              :   uint32_t purse_account_limit,
    1145              :   const struct TALER_MasterPublicKeyP *master_pub,
    1146              :   const struct TALER_MasterSignatureP *master_sig)
    1147              : {
    1148          296 :   struct TALER_MasterGlobalFeePS wf = {
    1149          148 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_GLOBAL_FEES),
    1150          148 :     .purpose.size = htonl (sizeof (wf)),
    1151          148 :     .start_date = GNUNET_TIME_timestamp_hton (start_time),
    1152          148 :     .end_date = GNUNET_TIME_timestamp_hton (end_time),
    1153          148 :     .purse_timeout = GNUNET_TIME_relative_hton (purse_timeout),
    1154          148 :     .history_expiration = GNUNET_TIME_relative_hton (history_expiration),
    1155          148 :     .purse_account_limit = htonl (purse_account_limit)
    1156              :   };
    1157              : 
    1158          148 :   TALER_global_fee_set_hton (&wf.fees,
    1159              :                              fees);
    1160              :   return
    1161          148 :     GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_GLOBAL_FEES,
    1162              :                                 &wf,
    1163              :                                 &master_sig->eddsa_signature,
    1164              :                                 &master_pub->eddsa_pub);
    1165              : }
    1166              : 
    1167              : 
    1168              : GNUNET_NETWORK_STRUCT_BEGIN
    1169              : 
    1170              : /**
    1171              :  * @brief Signature made by the exchange offline key over the manifest of
    1172              :  * an extension.
    1173              :  */
    1174              : struct TALER_MasterExtensionManifestPS
    1175              : {
    1176              :   /**
    1177              :    * Purpose is #TALER_SIGNATURE_MASTER_EXTENSION.   Signed
    1178              :    * by a `struct TALER_MasterPublicKeyP` using EdDSA.
    1179              :    */
    1180              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    1181              : 
    1182              :   /**
    1183              :    * Hash of the JSON object that represents the manifests of extensions.
    1184              :    */
    1185              :   struct TALER_ExtensionManifestsHashP h_manifest GNUNET_PACKED;
    1186              : };
    1187              : 
    1188              : GNUNET_NETWORK_STRUCT_END
    1189              : 
    1190              : 
    1191              : void
    1192            0 : TALER_exchange_offline_extension_manifests_hash_sign (
    1193              :   const struct TALER_ExtensionManifestsHashP *h_manifest,
    1194              :   const struct TALER_MasterPrivateKeyP *master_priv,
    1195              :   struct TALER_MasterSignatureP *master_sig)
    1196              : {
    1197            0 :   struct TALER_MasterExtensionManifestPS ec = {
    1198            0 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_EXTENSION),
    1199            0 :     .purpose.size = htonl (sizeof(ec)),
    1200              :     .h_manifest = *h_manifest
    1201              :   };
    1202            0 :   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
    1203              :                             &ec,
    1204              :                             &master_sig->eddsa_signature);
    1205            0 : }
    1206              : 
    1207              : 
    1208              : enum GNUNET_GenericReturnValue
    1209            0 : TALER_exchange_offline_extension_manifests_hash_verify (
    1210              :   const struct TALER_ExtensionManifestsHashP *h_manifest,
    1211              :   const struct TALER_MasterPublicKeyP *master_pub,
    1212              :   const struct TALER_MasterSignatureP *master_sig
    1213              :   )
    1214              : {
    1215            0 :   struct TALER_MasterExtensionManifestPS ec = {
    1216            0 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_EXTENSION),
    1217            0 :     .purpose.size = htonl (sizeof(ec)),
    1218              :     .h_manifest = *h_manifest
    1219              :   };
    1220              : 
    1221            0 :   return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_EXTENSION,
    1222              :                                      &ec,
    1223              :                                      &master_sig->eddsa_signature,
    1224              :                                      &master_pub->eddsa_pub);
    1225              : }
    1226              : 
    1227              : 
    1228              : GNUNET_NETWORK_STRUCT_BEGIN
    1229              : 
    1230              : /**
    1231              :  * @brief Information signed by the exchange's master
    1232              :  * key affirming the IBAN details for the exchange.
    1233              :  */
    1234              : struct TALER_MasterWireDetailsPS
    1235              : {
    1236              : 
    1237              :   /**
    1238              :    * Purpose is #TALER_SIGNATURE_MASTER_WIRE_DETAILS.
    1239              :    */
    1240              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    1241              : 
    1242              :   /**
    1243              :    * Hash over the account holder's payto:// URL.
    1244              :    */
    1245              :   struct TALER_FullPaytoHashP h_wire_details GNUNET_PACKED;
    1246              : 
    1247              :   /**
    1248              :    * Hash over the conversion URL, all zeros if there
    1249              :    * is no conversion URL.
    1250              :    */
    1251              :   struct GNUNET_HashCode h_conversion_url;
    1252              : 
    1253              :   /**
    1254              :    * Hash over the open banking gateway URL, all zeros if there
    1255              :    * is no open banking gateway URL.
    1256              :    */
    1257              :   struct GNUNET_HashCode h_open_banking_gateway;
    1258              : 
    1259              :   /**
    1260              :    * Hash over the wire transfer gateway URL, all zeros if there
    1261              :    * is no wire transfer gateway URL.
    1262              :    */
    1263              :   struct GNUNET_HashCode h_wire_transfer_gateway;
    1264              : 
    1265              :   /**
    1266              :    * Hash over the debit restrictions.
    1267              :    */
    1268              :   struct GNUNET_HashCode h_debit_restrictions;
    1269              : 
    1270              :   /**
    1271              :    * Hash over the credit restrictions.
    1272              :    */
    1273              :   struct GNUNET_HashCode h_credit_restrictions;
    1274              : 
    1275              : };
    1276              : 
    1277              : /**
    1278              :  * @brief Information signed by the exchange's master
    1279              :  * key affirming the IBAN details for the exchange.
    1280              :  */
    1281              : struct TALER_MasterWireDetails32PS
    1282              : {
    1283              : 
    1284              :   /**
    1285              :    * Purpose is #TALER_SIGNATURE_MASTER_WIRE_DETAILS.
    1286              :    */
    1287              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    1288              : 
    1289              :   /**
    1290              :    * Hash over the account holder's payto:// URL.
    1291              :    */
    1292              :   struct TALER_FullPaytoHashP h_wire_details GNUNET_PACKED;
    1293              : 
    1294              :   /**
    1295              :    * Hash over the conversion URL, all zeros if there
    1296              :    * is no conversion URL.
    1297              :    */
    1298              :   struct GNUNET_HashCode h_conversion_url;
    1299              : 
    1300              :   /**
    1301              :    * Hash over the debit restrictions.
    1302              :    */
    1303              :   struct GNUNET_HashCode h_debit_restrictions;
    1304              : 
    1305              :   /**
    1306              :    * Hash over the credit restrictions.
    1307              :    */
    1308              :   struct GNUNET_HashCode h_credit_restrictions;
    1309              : 
    1310              : };
    1311              : 
    1312              : GNUNET_NETWORK_STRUCT_END
    1313              : 
    1314              : 
    1315              : enum GNUNET_GenericReturnValue
    1316           46 : TALER_exchange_wire_signature_check32 (
    1317              :   const struct TALER_FullPayto payto_uri,
    1318              :   const char *conversion_url,
    1319              :   const json_t *debit_restrictions,
    1320              :   const json_t *credit_restrictions,
    1321              :   const struct TALER_MasterPublicKeyP *master_pub,
    1322              :   const struct TALER_MasterSignatureP *master_sig)
    1323              : {
    1324           46 :   struct TALER_MasterWireDetails32PS wd = {
    1325           46 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_WIRE_DETAILS),
    1326           46 :     .purpose.size = htonl (sizeof (wd))
    1327              :   };
    1328              : 
    1329           46 :   TALER_full_payto_hash (payto_uri,
    1330              :                          &wd.h_wire_details);
    1331           46 :   if (NULL != conversion_url)
    1332            0 :     GNUNET_CRYPTO_hash (conversion_url,
    1333            0 :                         strlen (conversion_url) + 1,
    1334              :                         &wd.h_conversion_url);
    1335           46 :   TALER_json_hash (debit_restrictions,
    1336              :                    &wd.h_debit_restrictions);
    1337           46 :   TALER_json_hash (credit_restrictions,
    1338              :                    &wd.h_credit_restrictions);
    1339           46 :   return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_WIRE_DETAILS,
    1340              :                                      &wd,
    1341              :                                      &master_sig->eddsa_signature,
    1342              :                                      &master_pub->eddsa_pub);
    1343              : }
    1344              : 
    1345              : 
    1346              : enum GNUNET_GenericReturnValue
    1347           93 : TALER_exchange_wire_signature_check (
    1348              :   const struct TALER_FullPayto payto_uri,
    1349              :   const char *conversion_url,
    1350              :   const char *open_banking_gateway,
    1351              :   const char *wire_transfer_gateway,
    1352              :   const json_t *debit_restrictions,
    1353              :   const json_t *credit_restrictions,
    1354              :   const struct TALER_MasterPublicKeyP *master_pub,
    1355              :   const struct TALER_MasterSignatureP *master_sig)
    1356              : {
    1357           93 :   struct TALER_MasterWireDetailsPS wd = {
    1358           93 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_WIRE_DETAILS),
    1359           93 :     .purpose.size = htonl (sizeof (wd))
    1360              :   };
    1361              : 
    1362           93 :   TALER_full_payto_hash (payto_uri,
    1363              :                          &wd.h_wire_details);
    1364           93 :   if (NULL != conversion_url)
    1365            1 :     GNUNET_CRYPTO_hash (conversion_url,
    1366            1 :                         strlen (conversion_url) + 1,
    1367              :                         &wd.h_conversion_url);
    1368           93 :   if (NULL != open_banking_gateway)
    1369            2 :     GNUNET_CRYPTO_hash (open_banking_gateway,
    1370            2 :                         strlen (open_banking_gateway) + 1,
    1371              :                         &wd.h_open_banking_gateway);
    1372           93 :   if (NULL != wire_transfer_gateway)
    1373            0 :     GNUNET_CRYPTO_hash (wire_transfer_gateway,
    1374            0 :                         strlen (wire_transfer_gateway) + 1,
    1375              :                         &wd.h_wire_transfer_gateway);
    1376           93 :   TALER_json_hash (debit_restrictions,
    1377              :                    &wd.h_debit_restrictions);
    1378           93 :   TALER_json_hash (credit_restrictions,
    1379              :                    &wd.h_credit_restrictions);
    1380           93 :   return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_WIRE_DETAILS,
    1381              :                                      &wd,
    1382              :                                      &master_sig->eddsa_signature,
    1383              :                                      &master_pub->eddsa_pub);
    1384              : }
    1385              : 
    1386              : 
    1387              : void
    1388           24 : TALER_exchange_wire_signature_make (
    1389              :   const struct TALER_FullPayto payto_uri,
    1390              :   const char *conversion_url,
    1391              :   const char *open_banking_gateway,
    1392              :   const char *wire_transfer_gateway,
    1393              :   const json_t *debit_restrictions,
    1394              :   const json_t *credit_restrictions,
    1395              :   const struct TALER_MasterPrivateKeyP *master_priv,
    1396              :   struct TALER_MasterSignatureP *master_sig)
    1397              : {
    1398           24 :   struct TALER_MasterWireDetailsPS wd = {
    1399           24 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_WIRE_DETAILS),
    1400           24 :     .purpose.size = htonl (sizeof (wd))
    1401              :   };
    1402              : 
    1403           24 :   TALER_full_payto_hash (payto_uri,
    1404              :                          &wd.h_wire_details);
    1405           24 :   if (NULL != conversion_url)
    1406            0 :     GNUNET_CRYPTO_hash (conversion_url,
    1407            0 :                         strlen (conversion_url) + 1,
    1408              :                         &wd.h_conversion_url);
    1409           24 :   if (NULL != open_banking_gateway)
    1410            1 :     GNUNET_CRYPTO_hash (open_banking_gateway,
    1411            1 :                         strlen (open_banking_gateway) + 1,
    1412              :                         &wd.h_open_banking_gateway);
    1413           24 :   if (NULL != wire_transfer_gateway)
    1414            0 :     GNUNET_CRYPTO_hash (wire_transfer_gateway,
    1415            0 :                         strlen (wire_transfer_gateway) + 1,
    1416              :                         &wd.h_wire_transfer_gateway);
    1417           24 :   TALER_json_hash (debit_restrictions,
    1418              :                    &wd.h_debit_restrictions);
    1419           24 :   TALER_json_hash (credit_restrictions,
    1420              :                    &wd.h_credit_restrictions);
    1421           24 :   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
    1422              :                             &wd,
    1423              :                             &master_sig->eddsa_signature);
    1424           24 : }
    1425              : 
    1426              : 
    1427              : GNUNET_NETWORK_STRUCT_BEGIN
    1428              : 
    1429              : /**
    1430              :  * Message signed by account to merge a purse into a reserve.
    1431              :  */
    1432              : struct TALER_PartnerConfigurationPS
    1433              : {
    1434              : 
    1435              :   /**
    1436              :    * Purpose is #TALER_SIGNATURE_MASTER_PARNTER_DETAILS
    1437              :    */
    1438              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    1439              :   struct TALER_MasterPublicKeyP partner_pub;
    1440              :   struct GNUNET_TIME_TimestampNBO start_date;
    1441              :   struct GNUNET_TIME_TimestampNBO end_date;
    1442              :   struct GNUNET_TIME_RelativeNBO wad_frequency;
    1443              :   struct TALER_AmountNBO wad_fee;
    1444              :   struct GNUNET_HashCode h_url;
    1445              : };
    1446              : 
    1447              : GNUNET_NETWORK_STRUCT_END
    1448              : 
    1449              : 
    1450              : void
    1451            0 : TALER_exchange_offline_partner_details_sign (
    1452              :   const struct TALER_MasterPublicKeyP *partner_pub,
    1453              :   struct GNUNET_TIME_Timestamp start_date,
    1454              :   struct GNUNET_TIME_Timestamp end_date,
    1455              :   struct GNUNET_TIME_Relative wad_frequency,
    1456              :   const struct TALER_Amount *wad_fee,
    1457              :   const char *partner_base_url,
    1458              :   const struct TALER_MasterPrivateKeyP *master_priv,
    1459              :   struct TALER_MasterSignatureP *master_sig)
    1460              : {
    1461            0 :   struct TALER_PartnerConfigurationPS wd = {
    1462            0 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_PARTNER_DETAILS),
    1463            0 :     .purpose.size = htonl (sizeof (wd)),
    1464              :     .partner_pub = *partner_pub,
    1465            0 :     .start_date = GNUNET_TIME_timestamp_hton (start_date),
    1466            0 :     .end_date = GNUNET_TIME_timestamp_hton (end_date),
    1467            0 :     .wad_frequency = GNUNET_TIME_relative_hton (wad_frequency),
    1468              :   };
    1469              : 
    1470            0 :   GNUNET_CRYPTO_hash (partner_base_url,
    1471            0 :                       strlen (partner_base_url) + 1,
    1472              :                       &wd.h_url);
    1473            0 :   TALER_amount_hton (&wd.wad_fee,
    1474              :                      wad_fee);
    1475            0 :   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
    1476              :                             &wd,
    1477              :                             &master_sig->eddsa_signature);
    1478            0 : }
    1479              : 
    1480              : 
    1481              : enum GNUNET_GenericReturnValue
    1482            0 : TALER_exchange_offline_partner_details_verify (
    1483              :   const struct TALER_MasterPublicKeyP *partner_pub,
    1484              :   struct GNUNET_TIME_Timestamp start_date,
    1485              :   struct GNUNET_TIME_Timestamp end_date,
    1486              :   struct GNUNET_TIME_Relative wad_frequency,
    1487              :   const struct TALER_Amount *wad_fee,
    1488              :   const char *partner_base_url,
    1489              :   const struct TALER_MasterPublicKeyP *master_pub,
    1490              :   const struct TALER_MasterSignatureP *master_sig)
    1491              : {
    1492            0 :   struct TALER_PartnerConfigurationPS wd = {
    1493            0 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_PARTNER_DETAILS),
    1494            0 :     .purpose.size = htonl (sizeof (wd)),
    1495              :     .partner_pub = *partner_pub,
    1496            0 :     .start_date = GNUNET_TIME_timestamp_hton (start_date),
    1497            0 :     .end_date = GNUNET_TIME_timestamp_hton (end_date),
    1498            0 :     .wad_frequency = GNUNET_TIME_relative_hton (wad_frequency),
    1499              :   };
    1500              : 
    1501            0 :   GNUNET_CRYPTO_hash (partner_base_url,
    1502            0 :                       strlen (partner_base_url) + 1,
    1503              :                       &wd.h_url);
    1504            0 :   TALER_amount_hton (&wd.wad_fee,
    1505              :                      wad_fee);
    1506            0 :   return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_PARTNER_DETAILS,
    1507              :                                      &wd,
    1508              :                                      &master_sig->eddsa_signature,
    1509              :                                      &master_pub->eddsa_pub);
    1510              : }
    1511              : 
    1512              : 
    1513              : GNUNET_NETWORK_STRUCT_BEGIN
    1514              : 
    1515              : /**
    1516              :  * Message signed by account to drain profits
    1517              :  * from the escrow account of the exchange.
    1518              :  */
    1519              : struct TALER_DrainProfitPS
    1520              : {
    1521              : 
    1522              :   /**
    1523              :    * Purpose is #TALER_SIGNATURE_MASTER_DRAIN_PROFITS
    1524              :    */
    1525              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    1526              :   struct TALER_WireTransferIdentifierRawP wtid;
    1527              :   struct GNUNET_TIME_TimestampNBO date;
    1528              :   struct TALER_AmountNBO amount;
    1529              :   struct GNUNET_HashCode h_section;
    1530              :   struct TALER_FullPaytoHashP h_payto;
    1531              : };
    1532              : 
    1533              : GNUNET_NETWORK_STRUCT_END
    1534              : 
    1535              : 
    1536              : void
    1537            0 : TALER_exchange_offline_profit_drain_sign (
    1538              :   const struct TALER_WireTransferIdentifierRawP *wtid,
    1539              :   struct GNUNET_TIME_Timestamp date,
    1540              :   const struct TALER_Amount *amount,
    1541              :   const char *account_section,
    1542              :   const struct TALER_FullPayto payto_uri,
    1543              :   const struct TALER_MasterPrivateKeyP *master_priv,
    1544              :   struct TALER_MasterSignatureP *master_sig)
    1545              : {
    1546            0 :   struct TALER_DrainProfitPS wd = {
    1547            0 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_DRAIN_PROFIT),
    1548            0 :     .purpose.size = htonl (sizeof (wd)),
    1549              :     .wtid = *wtid,
    1550            0 :     .date = GNUNET_TIME_timestamp_hton (date),
    1551              :   };
    1552              : 
    1553            0 :   GNUNET_CRYPTO_hash (account_section,
    1554            0 :                       strlen (account_section) + 1,
    1555              :                       &wd.h_section);
    1556            0 :   TALER_full_payto_hash (payto_uri,
    1557              :                          &wd.h_payto);
    1558            0 :   TALER_amount_hton (&wd.amount,
    1559              :                      amount);
    1560            0 :   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
    1561              :                             &wd,
    1562              :                             &master_sig->eddsa_signature);
    1563            0 : }
    1564              : 
    1565              : 
    1566              : enum GNUNET_GenericReturnValue
    1567            0 : TALER_exchange_offline_profit_drain_verify (
    1568              :   const struct TALER_WireTransferIdentifierRawP *wtid,
    1569              :   struct GNUNET_TIME_Timestamp date,
    1570              :   const struct TALER_Amount *amount,
    1571              :   const char *account_section,
    1572              :   const struct TALER_FullPayto payto_uri,
    1573              :   const struct TALER_MasterPublicKeyP *master_pub,
    1574              :   const struct TALER_MasterSignatureP *master_sig)
    1575              : {
    1576            0 :   struct TALER_DrainProfitPS wd = {
    1577            0 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_DRAIN_PROFIT),
    1578            0 :     .purpose.size = htonl (sizeof (wd)),
    1579              :     .wtid = *wtid,
    1580            0 :     .date = GNUNET_TIME_timestamp_hton (date),
    1581              :   };
    1582              : 
    1583            0 :   GNUNET_CRYPTO_hash (account_section,
    1584            0 :                       strlen (account_section) + 1,
    1585              :                       &wd.h_section);
    1586            0 :   TALER_full_payto_hash (payto_uri,
    1587              :                          &wd.h_payto);
    1588            0 :   TALER_amount_hton (&wd.amount,
    1589              :                      amount);
    1590            0 :   return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_DRAIN_PROFIT,
    1591              :                                      &wd,
    1592              :                                      &master_sig->eddsa_signature,
    1593              :                                      &master_pub->eddsa_pub);
    1594              : }
    1595              : 
    1596              : 
    1597              : /* end of offline_signatures.c */
        

Generated by: LCOV version 2.0-1