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

Generated by: LCOV version 2.0-1