LCOV - code coverage report
Current view: top level - util - offline_signatures.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 212 274 77.4 %
Date: 2025-06-05 21:03:14 Functions: 22 30 73.3 %

          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 "platform.h"
      22             : #include "taler_util.h"
      23             : #include "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_EccSignaturePurpose 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_EccSignaturePurpose 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          10 : 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          20 :   struct TALER_MasterAddAuditorPS kv = {
     161          10 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_ADD_AUDITOR),
     162          10 :     .purpose.size = htonl (sizeof (kv)),
     163          10 :     .start_date = GNUNET_TIME_timestamp_hton (start_date),
     164             :     .auditor_pub = *auditor_pub,
     165             :   };
     166             : 
     167          10 :   GNUNET_CRYPTO_hash (auditor_url,
     168          10 :                       strlen (auditor_url) + 1,
     169             :                       &kv.h_auditor_url);
     170          10 :   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
     171             :                             &kv,
     172             :                             &master_sig->eddsa_signature);
     173          10 : }
     174             : 
     175             : 
     176             : enum GNUNET_GenericReturnValue
     177          12 : 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          24 :   struct TALER_MasterAddAuditorPS aa = {
     185          12 :     .purpose.purpose = htonl (
     186             :       TALER_SIGNATURE_MASTER_ADD_AUDITOR),
     187          12 :     .purpose.size = htonl (sizeof (aa)),
     188          12 :     .start_date = GNUNET_TIME_timestamp_hton (start_date),
     189             :     .auditor_pub = *auditor_pub
     190             :   };
     191             : 
     192          12 :   GNUNET_CRYPTO_hash (auditor_url,
     193          12 :                       strlen (auditor_url) + 1,
     194             :                       &aa.h_auditor_url);
     195          12 :   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_EccSignaturePurpose 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_EccSignaturePurpose 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_EccSignaturePurpose 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_EccSignaturePurpose 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          67 : 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         134 :   struct TALER_ExchangeSigningKeyValidityPS skv = {
     455          67 :     .purpose.purpose = htonl (
     456             :       TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY),
     457          67 :     .purpose.size = htonl (sizeof (skv)),
     458          67 :     .start = GNUNET_TIME_timestamp_hton (start_sign),
     459          67 :     .expire = GNUNET_TIME_timestamp_hton (end_sign),
     460          67 :     .end = GNUNET_TIME_timestamp_hton (end_legal),
     461             :     .signkey_pub = *exchange_pub
     462             :   };
     463             : 
     464          67 :   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
     465             :                             &skv,
     466             :                             &master_sig->eddsa_signature);
     467          67 : }
     468             : 
     469             : 
     470             : enum GNUNET_GenericReturnValue
     471         345 : 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         690 :   struct TALER_ExchangeSigningKeyValidityPS skv = {
     480         345 :     .purpose.purpose = htonl (
     481             :       TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY),
     482         345 :     .purpose.size = htonl (sizeof (skv)),
     483         345 :     .start = GNUNET_TIME_timestamp_hton (start_sign),
     484         345 :     .expire = GNUNET_TIME_timestamp_hton (end_sign),
     485         345 :     .end = GNUNET_TIME_timestamp_hton (end_legal),
     486             :     .signkey_pub = *exchange_pub
     487             :   };
     488             : 
     489             :   return
     490         345 :     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_EccSignaturePurpose 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        6220 : 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       12440 :   struct TALER_DenominationKeyValidityPS issue = {
     596             :     .purpose.purpose
     597        6220 :       = htonl (TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY),
     598             :     .purpose.size
     599        6220 :       = htonl (sizeof (issue)),
     600        6220 :     .start = GNUNET_TIME_timestamp_hton (stamp_start),
     601        6220 :     .expire_withdraw = GNUNET_TIME_timestamp_hton (stamp_expire_withdraw),
     602        6220 :     .expire_deposit = GNUNET_TIME_timestamp_hton (stamp_expire_deposit),
     603        6220 :     .expire_legal = GNUNET_TIME_timestamp_hton (stamp_expire_legal),
     604             :     .denom_hash = *h_denom_pub
     605             :   };
     606             : 
     607        6220 :   GNUNET_CRYPTO_eddsa_key_get_public (&master_priv->eddsa_priv,
     608             :                                       &issue.master.eddsa_pub);
     609        6220 :   TALER_amount_hton (&issue.value,
     610             :                      coin_value);
     611        6220 :   TALER_denom_fee_set_hton (&issue.fees,
     612             :                             fees);
     613        6220 :   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
     614             :                             &issue,
     615             :                             &master_sig->eddsa_signature);
     616        6220 : }
     617             : 
     618             : 
     619             : enum GNUNET_GenericReturnValue
     620       34668 : 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       69336 :   struct TALER_DenominationKeyValidityPS dkv = {
     632       34668 :     .purpose.purpose = htonl (
     633             :       TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY),
     634       34668 :     .purpose.size = htonl (sizeof (dkv)),
     635             :     .master = *master_pub,
     636       34668 :     .start = GNUNET_TIME_timestamp_hton (stamp_start),
     637       34668 :     .expire_withdraw = GNUNET_TIME_timestamp_hton (stamp_expire_withdraw),
     638       34668 :     .expire_deposit = GNUNET_TIME_timestamp_hton (stamp_expire_deposit),
     639       34668 :     .expire_legal = GNUNET_TIME_timestamp_hton (stamp_expire_legal),
     640             :     .denom_hash = *h_denom_pub
     641             :   };
     642             : 
     643       34668 :   TALER_amount_hton (&dkv.value,
     644             :                      coin_value);
     645       34668 :   TALER_denom_fee_set_hton (&dkv.fees,
     646             :                             fees);
     647             :   return
     648       34668 :     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_EccSignaturePurpose 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 debit restrictions.
     689             :    */
     690             :   struct GNUNET_HashCode h_debit_restrictions;
     691             : 
     692             :   /**
     693             :    * Hash over the credit restrictions.
     694             :    */
     695             :   struct GNUNET_HashCode h_credit_restrictions;
     696             : };
     697             : 
     698             : GNUNET_NETWORK_STRUCT_END
     699             : 
     700             : 
     701             : void
     702          25 : TALER_exchange_offline_wire_add_sign (
     703             :   const struct TALER_FullPayto payto_uri,
     704             :   const char *conversion_url,
     705             :   const json_t *debit_restrictions,
     706             :   const json_t *credit_restrictions,
     707             :   struct GNUNET_TIME_Timestamp now,
     708             :   const struct TALER_MasterPrivateKeyP *master_priv,
     709             :   struct TALER_MasterSignatureP *master_sig)
     710             : {
     711          25 :   struct TALER_MasterAddWirePS kv = {
     712          25 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_ADD_WIRE),
     713          25 :     .purpose.size = htonl (sizeof (kv)),
     714          25 :     .start_date = GNUNET_TIME_timestamp_hton (now),
     715             :   };
     716             : 
     717          25 :   TALER_full_payto_hash (payto_uri,
     718             :                          &kv.h_payto);
     719          25 :   if (NULL != conversion_url)
     720           0 :     GNUNET_CRYPTO_hash (conversion_url,
     721           0 :                         strlen (conversion_url) + 1,
     722             :                         &kv.h_conversion_url);
     723          25 :   TALER_json_hash (debit_restrictions,
     724             :                    &kv.h_debit_restrictions);
     725          25 :   TALER_json_hash (credit_restrictions,
     726             :                    &kv.h_credit_restrictions);
     727          25 :   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
     728             :                             &kv,
     729             :                             &master_sig->eddsa_signature);
     730          25 : }
     731             : 
     732             : 
     733             : enum GNUNET_GenericReturnValue
     734          27 : TALER_exchange_offline_wire_add_verify (
     735             :   const struct TALER_FullPayto payto_uri,
     736             :   const char *conversion_url,
     737             :   const json_t *debit_restrictions,
     738             :   const json_t *credit_restrictions,
     739             :   struct GNUNET_TIME_Timestamp sign_time,
     740             :   const struct TALER_MasterPublicKeyP *master_pub,
     741             :   const struct TALER_MasterSignatureP *master_sig)
     742             : {
     743          27 :   struct TALER_MasterAddWirePS aw = {
     744          27 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_ADD_WIRE),
     745          27 :     .purpose.size = htonl (sizeof (aw)),
     746          27 :     .start_date = GNUNET_TIME_timestamp_hton (sign_time),
     747             :   };
     748             : 
     749          27 :   TALER_full_payto_hash (payto_uri,
     750             :                          &aw.h_payto);
     751          27 :   if (NULL != conversion_url)
     752           0 :     GNUNET_CRYPTO_hash (conversion_url,
     753           0 :                         strlen (conversion_url) + 1,
     754             :                         &aw.h_conversion_url);
     755          27 :   TALER_json_hash (debit_restrictions,
     756             :                    &aw.h_debit_restrictions);
     757          27 :   TALER_json_hash (credit_restrictions,
     758             :                    &aw.h_credit_restrictions);
     759             :   return
     760          27 :     GNUNET_CRYPTO_eddsa_verify (
     761             :     TALER_SIGNATURE_MASTER_ADD_WIRE,
     762             :     &aw,
     763             :     &master_sig->eddsa_signature,
     764             :     &master_pub->eddsa_pub);
     765             : }
     766             : 
     767             : 
     768             : GNUNET_NETWORK_STRUCT_BEGIN
     769             : 
     770             : /**
     771             :  * @brief Signature made by the exchange offline key over the information of
     772             :  * a  wire method to be removed to the exchange's set of active accounts.
     773             :  */
     774             : struct TALER_MasterDelWirePS
     775             : {
     776             : 
     777             :   /**
     778             :    * Purpose is #TALER_SIGNATURE_MASTER_DEL_WIRE.   Signed
     779             :    * by a `struct TALER_MasterPublicKeyP` using EdDSA.
     780             :    */
     781             :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
     782             : 
     783             :   /**
     784             :    * Time of the change.
     785             :    */
     786             :   struct GNUNET_TIME_TimestampNBO end_date;
     787             : 
     788             :   /**
     789             :    * Hash over the exchange's payto URI.
     790             :    */
     791             :   struct TALER_FullPaytoHashP h_payto GNUNET_PACKED;
     792             : 
     793             : };
     794             : 
     795             : GNUNET_NETWORK_STRUCT_END
     796             : 
     797             : 
     798             : void
     799           4 : TALER_exchange_offline_wire_del_sign (
     800             :   const struct TALER_FullPayto payto_uri,
     801             :   struct GNUNET_TIME_Timestamp now,
     802             :   const struct TALER_MasterPrivateKeyP *master_priv,
     803             :   struct TALER_MasterSignatureP *master_sig)
     804             : {
     805           4 :   struct TALER_MasterDelWirePS kv = {
     806           4 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_DEL_WIRE),
     807           4 :     .purpose.size = htonl (sizeof (kv)),
     808           4 :     .end_date = GNUNET_TIME_timestamp_hton (now),
     809             :   };
     810             : 
     811           4 :   TALER_full_payto_hash (payto_uri,
     812             :                          &kv.h_payto);
     813           4 :   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
     814             :                             &kv,
     815             :                             &master_sig->eddsa_signature);
     816           4 : }
     817             : 
     818             : 
     819             : enum GNUNET_GenericReturnValue
     820           6 : TALER_exchange_offline_wire_del_verify (
     821             :   const struct TALER_FullPayto payto_uri,
     822             :   struct GNUNET_TIME_Timestamp sign_time,
     823             :   const struct TALER_MasterPublicKeyP *master_pub,
     824             :   const struct TALER_MasterSignatureP *master_sig)
     825             : {
     826           6 :   struct TALER_MasterDelWirePS aw = {
     827           6 :     .purpose.purpose = htonl (
     828             :       TALER_SIGNATURE_MASTER_DEL_WIRE),
     829           6 :     .purpose.size = htonl (sizeof (aw)),
     830           6 :     .end_date = GNUNET_TIME_timestamp_hton (sign_time),
     831             :   };
     832             : 
     833           6 :   TALER_full_payto_hash (payto_uri,
     834             :                          &aw.h_payto);
     835           6 :   return GNUNET_CRYPTO_eddsa_verify (
     836             :     TALER_SIGNATURE_MASTER_DEL_WIRE,
     837             :     &aw,
     838             :     &master_sig->eddsa_signature,
     839             :     &master_pub->eddsa_pub);
     840             : }
     841             : 
     842             : 
     843             : GNUNET_NETWORK_STRUCT_BEGIN
     844             : 
     845             : /**
     846             :  * @brief Information signed by the exchange's master
     847             :  * key stating the wire fee to be paid per wire transfer.
     848             :  */
     849             : struct TALER_MasterWireFeePS
     850             : {
     851             : 
     852             :   /**
     853             :    * Purpose is #TALER_SIGNATURE_MASTER_WIRE_FEES.
     854             :    */
     855             :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
     856             : 
     857             :   /**
     858             :    * Hash over the wire method (yes, H("x-taler-bank") or H("iban")), in lower
     859             :    * case, including 0-terminator.  Used to uniquely identify which
     860             :    * wire method these fees apply to.
     861             :    */
     862             :   struct GNUNET_HashCode h_wire_method;
     863             : 
     864             :   /**
     865             :    * Start date when the fee goes into effect.
     866             :    */
     867             :   struct GNUNET_TIME_TimestampNBO start_date;
     868             : 
     869             :   /**
     870             :    * End date when the fee stops being in effect (exclusive)
     871             :    */
     872             :   struct GNUNET_TIME_TimestampNBO end_date;
     873             : 
     874             :   /**
     875             :    * Fees charged for wire transfers using the
     876             :    * given wire method.
     877             :    */
     878             :   struct TALER_WireFeeSetNBOP fees;
     879             : 
     880             : };
     881             : 
     882             : GNUNET_NETWORK_STRUCT_END
     883             : 
     884             : 
     885             : void
     886          27 : TALER_exchange_offline_wire_fee_sign (
     887             :   const char *payment_method,
     888             :   struct GNUNET_TIME_Timestamp start_time,
     889             :   struct GNUNET_TIME_Timestamp end_time,
     890             :   const struct TALER_WireFeeSet *fees,
     891             :   const struct TALER_MasterPrivateKeyP *master_priv,
     892             :   struct TALER_MasterSignatureP *master_sig)
     893             : {
     894          27 :   struct TALER_MasterWireFeePS kv = {
     895          27 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_WIRE_FEES),
     896          27 :     .purpose.size = htonl (sizeof (kv)),
     897          27 :     .start_date = GNUNET_TIME_timestamp_hton (start_time),
     898          27 :     .end_date = GNUNET_TIME_timestamp_hton (end_time),
     899             :   };
     900             : 
     901          27 :   GNUNET_CRYPTO_hash (payment_method,
     902          27 :                       strlen (payment_method) + 1,
     903             :                       &kv.h_wire_method);
     904          27 :   TALER_wire_fee_set_hton (&kv.fees,
     905             :                            fees);
     906          27 :   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
     907             :                             &kv,
     908             :                             &master_sig->eddsa_signature);
     909          27 : }
     910             : 
     911             : 
     912             : enum GNUNET_GenericReturnValue
     913         134 : TALER_exchange_offline_wire_fee_verify (
     914             :   const char *payment_method,
     915             :   struct GNUNET_TIME_Timestamp start_time,
     916             :   struct GNUNET_TIME_Timestamp end_time,
     917             :   const struct TALER_WireFeeSet *fees,
     918             :   const struct TALER_MasterPublicKeyP *master_pub,
     919             :   const struct TALER_MasterSignatureP *master_sig)
     920             : {
     921         134 :   struct TALER_MasterWireFeePS wf = {
     922         134 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_WIRE_FEES),
     923         134 :     .purpose.size = htonl (sizeof (wf)),
     924         134 :     .start_date = GNUNET_TIME_timestamp_hton (start_time),
     925         134 :     .end_date = GNUNET_TIME_timestamp_hton (end_time)
     926             :   };
     927             : 
     928         134 :   GNUNET_CRYPTO_hash (payment_method,
     929         134 :                       strlen (payment_method) + 1,
     930             :                       &wf.h_wire_method);
     931         134 :   TALER_wire_fee_set_hton (&wf.fees,
     932             :                            fees);
     933             :   return
     934         134 :     GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_WIRE_FEES,
     935             :                                 &wf,
     936             :                                 &master_sig->eddsa_signature,
     937             :                                 &master_pub->eddsa_pub);
     938             : }
     939             : 
     940             : 
     941             : GNUNET_NETWORK_STRUCT_BEGIN
     942             : 
     943             : /**
     944             :  * Global fees charged by the exchange independent of
     945             :  * denomination or wire method.
     946             :  */
     947             : struct TALER_MasterGlobalFeePS
     948             : {
     949             : 
     950             :   /**
     951             :    * Purpose is #TALER_SIGNATURE_MASTER_GLOBAL_FEES.
     952             :    */
     953             :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
     954             : 
     955             :   /**
     956             :    * Start date when the fee goes into effect.
     957             :    */
     958             :   struct GNUNET_TIME_TimestampNBO start_date;
     959             : 
     960             :   /**
     961             :    * End date when the fee stops being in effect (exclusive)
     962             :    */
     963             :   struct GNUNET_TIME_TimestampNBO end_date;
     964             : 
     965             :   /**
     966             :    * How long does an exchange keep a purse around after a purse
     967             :    * has expired (or been successfully merged)?  A 'GET' request
     968             :    * for a purse will succeed until the purse expiration time
     969             :    * plus this value.
     970             :    */
     971             :   struct GNUNET_TIME_RelativeNBO purse_timeout;
     972             : 
     973             :   /**
     974             :    * How long will the exchange preserve the account history?  After an
     975             :    * account was deleted/closed, the exchange will retain the account history
     976             :    * for legal reasons until this time.
     977             :    */
     978             :   struct GNUNET_TIME_RelativeNBO history_expiration;
     979             : 
     980             :   /**
     981             :    * Fee charged to the merchant per wire transfer.
     982             :    */
     983             :   struct TALER_GlobalFeeSetNBOP fees;
     984             : 
     985             :   /**
     986             :    * Number of concurrent purses that any
     987             :    * account holder is allowed to create without having
     988             :    * to pay the @e purse_fee. Here given in NBO.
     989             :    */
     990             :   uint32_t purse_account_limit;
     991             : 
     992             : };
     993             : 
     994             : GNUNET_NETWORK_STRUCT_END
     995             : 
     996             : 
     997             : void
     998          19 : TALER_exchange_offline_global_fee_sign (
     999             :   struct GNUNET_TIME_Timestamp start_time,
    1000             :   struct GNUNET_TIME_Timestamp end_time,
    1001             :   const struct TALER_GlobalFeeSet *fees,
    1002             :   struct GNUNET_TIME_Relative purse_timeout,
    1003             :   struct GNUNET_TIME_Relative history_expiration,
    1004             :   uint32_t purse_account_limit,
    1005             :   const struct TALER_MasterPrivateKeyP *master_priv,
    1006             :   struct TALER_MasterSignatureP *master_sig)
    1007             : {
    1008          38 :   struct TALER_MasterGlobalFeePS wf = {
    1009          19 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_GLOBAL_FEES),
    1010          19 :     .purpose.size = htonl (sizeof (wf)),
    1011          19 :     .start_date = GNUNET_TIME_timestamp_hton (start_time),
    1012          19 :     .end_date = GNUNET_TIME_timestamp_hton (end_time),
    1013          19 :     .purse_timeout = GNUNET_TIME_relative_hton (purse_timeout),
    1014          19 :     .history_expiration = GNUNET_TIME_relative_hton (history_expiration),
    1015          19 :     .purse_account_limit = htonl (purse_account_limit)
    1016             :   };
    1017             : 
    1018          19 :   TALER_global_fee_set_hton (&wf.fees,
    1019             :                              fees);
    1020          19 :   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
    1021             :                             &wf,
    1022             :                             &master_sig->eddsa_signature);
    1023          19 : }
    1024             : 
    1025             : 
    1026             : enum GNUNET_GenericReturnValue
    1027         108 : TALER_exchange_offline_global_fee_verify (
    1028             :   struct GNUNET_TIME_Timestamp start_time,
    1029             :   struct GNUNET_TIME_Timestamp end_time,
    1030             :   const struct TALER_GlobalFeeSet *fees,
    1031             :   struct GNUNET_TIME_Relative purse_timeout,
    1032             :   struct GNUNET_TIME_Relative history_expiration,
    1033             :   uint32_t purse_account_limit,
    1034             :   const struct TALER_MasterPublicKeyP *master_pub,
    1035             :   const struct TALER_MasterSignatureP *master_sig)
    1036             : {
    1037         216 :   struct TALER_MasterGlobalFeePS wf = {
    1038         108 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_GLOBAL_FEES),
    1039         108 :     .purpose.size = htonl (sizeof (wf)),
    1040         108 :     .start_date = GNUNET_TIME_timestamp_hton (start_time),
    1041         108 :     .end_date = GNUNET_TIME_timestamp_hton (end_time),
    1042         108 :     .purse_timeout = GNUNET_TIME_relative_hton (purse_timeout),
    1043         108 :     .history_expiration = GNUNET_TIME_relative_hton (history_expiration),
    1044         108 :     .purse_account_limit = htonl (purse_account_limit)
    1045             :   };
    1046             : 
    1047         108 :   TALER_global_fee_set_hton (&wf.fees,
    1048             :                              fees);
    1049             :   return
    1050         108 :     GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_GLOBAL_FEES,
    1051             :                                 &wf,
    1052             :                                 &master_sig->eddsa_signature,
    1053             :                                 &master_pub->eddsa_pub);
    1054             : }
    1055             : 
    1056             : 
    1057             : GNUNET_NETWORK_STRUCT_BEGIN
    1058             : 
    1059             : /**
    1060             :  * @brief Signature made by the exchange offline key over the manifest of
    1061             :  * an extension.
    1062             :  */
    1063             : struct TALER_MasterExtensionManifestPS
    1064             : {
    1065             :   /**
    1066             :    * Purpose is #TALER_SIGNATURE_MASTER_EXTENSION.   Signed
    1067             :    * by a `struct TALER_MasterPublicKeyP` using EdDSA.
    1068             :    */
    1069             :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
    1070             : 
    1071             :   /**
    1072             :    * Hash of the JSON object that represents the manifests of extensions.
    1073             :    */
    1074             :   struct TALER_ExtensionManifestsHashP h_manifest GNUNET_PACKED;
    1075             : };
    1076             : 
    1077             : GNUNET_NETWORK_STRUCT_END
    1078             : 
    1079             : 
    1080             : void
    1081           0 : TALER_exchange_offline_extension_manifests_hash_sign (
    1082             :   const struct TALER_ExtensionManifestsHashP *h_manifest,
    1083             :   const struct TALER_MasterPrivateKeyP *master_priv,
    1084             :   struct TALER_MasterSignatureP *master_sig)
    1085             : {
    1086           0 :   struct TALER_MasterExtensionManifestPS ec = {
    1087           0 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_EXTENSION),
    1088           0 :     .purpose.size = htonl (sizeof(ec)),
    1089             :     .h_manifest = *h_manifest
    1090             :   };
    1091           0 :   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
    1092             :                             &ec,
    1093             :                             &master_sig->eddsa_signature);
    1094           0 : }
    1095             : 
    1096             : 
    1097             : enum GNUNET_GenericReturnValue
    1098           0 : TALER_exchange_offline_extension_manifests_hash_verify (
    1099             :   const struct TALER_ExtensionManifestsHashP *h_manifest,
    1100             :   const struct TALER_MasterPublicKeyP *master_pub,
    1101             :   const struct TALER_MasterSignatureP *master_sig
    1102             :   )
    1103             : {
    1104           0 :   struct TALER_MasterExtensionManifestPS ec = {
    1105           0 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_EXTENSION),
    1106           0 :     .purpose.size = htonl (sizeof(ec)),
    1107             :     .h_manifest = *h_manifest
    1108             :   };
    1109             : 
    1110           0 :   return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_EXTENSION,
    1111             :                                      &ec,
    1112             :                                      &master_sig->eddsa_signature,
    1113             :                                      &master_pub->eddsa_pub);
    1114             : }
    1115             : 
    1116             : 
    1117             : GNUNET_NETWORK_STRUCT_BEGIN
    1118             : 
    1119             : /**
    1120             :  * @brief Information signed by the exchange's master
    1121             :  * key affirming the IBAN details for the exchange.
    1122             :  */
    1123             : struct TALER_MasterWireDetailsPS
    1124             : {
    1125             : 
    1126             :   /**
    1127             :    * Purpose is #TALER_SIGNATURE_MASTER_WIRE_DETAILS.
    1128             :    */
    1129             :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
    1130             : 
    1131             :   /**
    1132             :    * Hash over the account holder's payto:// URL.
    1133             :    */
    1134             :   struct TALER_FullPaytoHashP h_wire_details GNUNET_PACKED;
    1135             : 
    1136             :   /**
    1137             :    * Hash over the conversion URL, all zeros if there
    1138             :    * is no conversion URL.
    1139             :    */
    1140             :   struct GNUNET_HashCode h_conversion_url;
    1141             : 
    1142             :   /**
    1143             :    * Hash over the debit restrictions.
    1144             :    */
    1145             :   struct GNUNET_HashCode h_debit_restrictions;
    1146             : 
    1147             :   /**
    1148             :    * Hash over the credit restrictions.
    1149             :    */
    1150             :   struct GNUNET_HashCode h_credit_restrictions;
    1151             : 
    1152             : };
    1153             : 
    1154             : GNUNET_NETWORK_STRUCT_END
    1155             : 
    1156             : 
    1157             : enum GNUNET_GenericReturnValue
    1158         119 : TALER_exchange_wire_signature_check (
    1159             :   const struct TALER_FullPayto payto_uri,
    1160             :   const char *conversion_url,
    1161             :   const json_t *debit_restrictions,
    1162             :   const json_t *credit_restrictions,
    1163             :   const struct TALER_MasterPublicKeyP *master_pub,
    1164             :   const struct TALER_MasterSignatureP *master_sig)
    1165             : {
    1166         119 :   struct TALER_MasterWireDetailsPS wd = {
    1167         119 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_WIRE_DETAILS),
    1168         119 :     .purpose.size = htonl (sizeof (wd))
    1169             :   };
    1170             : 
    1171         119 :   TALER_full_payto_hash (payto_uri,
    1172             :                          &wd.h_wire_details);
    1173         119 :   if (NULL != conversion_url)
    1174           1 :     GNUNET_CRYPTO_hash (conversion_url,
    1175           1 :                         strlen (conversion_url) + 1,
    1176             :                         &wd.h_conversion_url);
    1177         119 :   TALER_json_hash (debit_restrictions,
    1178             :                    &wd.h_debit_restrictions);
    1179         119 :   TALER_json_hash (credit_restrictions,
    1180             :                    &wd.h_credit_restrictions);
    1181         119 :   return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_WIRE_DETAILS,
    1182             :                                      &wd,
    1183             :                                      &master_sig->eddsa_signature,
    1184             :                                      &master_pub->eddsa_pub);
    1185             : }
    1186             : 
    1187             : 
    1188             : void
    1189          26 : TALER_exchange_wire_signature_make (
    1190             :   const struct TALER_FullPayto payto_uri,
    1191             :   const char *conversion_url,
    1192             :   const json_t *debit_restrictions,
    1193             :   const json_t *credit_restrictions,
    1194             :   const struct TALER_MasterPrivateKeyP *master_priv,
    1195             :   struct TALER_MasterSignatureP *master_sig)
    1196             : {
    1197          26 :   struct TALER_MasterWireDetailsPS wd = {
    1198          26 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_WIRE_DETAILS),
    1199          26 :     .purpose.size = htonl (sizeof (wd))
    1200             :   };
    1201             : 
    1202          26 :   TALER_full_payto_hash (payto_uri,
    1203             :                          &wd.h_wire_details);
    1204          26 :   if (NULL != conversion_url)
    1205           0 :     GNUNET_CRYPTO_hash (conversion_url,
    1206           0 :                         strlen (conversion_url) + 1,
    1207             :                         &wd.h_conversion_url);
    1208          26 :   TALER_json_hash (debit_restrictions,
    1209             :                    &wd.h_debit_restrictions);
    1210          26 :   TALER_json_hash (credit_restrictions,
    1211             :                    &wd.h_credit_restrictions);
    1212          26 :   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
    1213             :                             &wd,
    1214             :                             &master_sig->eddsa_signature);
    1215          26 : }
    1216             : 
    1217             : 
    1218             : GNUNET_NETWORK_STRUCT_BEGIN
    1219             : 
    1220             : /**
    1221             :  * Message signed by account to merge a purse into a reserve.
    1222             :  */
    1223             : struct TALER_PartnerConfigurationPS
    1224             : {
    1225             : 
    1226             :   /**
    1227             :    * Purpose is #TALER_SIGNATURE_MASTER_PARNTER_DETAILS
    1228             :    */
    1229             :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
    1230             :   struct TALER_MasterPublicKeyP partner_pub;
    1231             :   struct GNUNET_TIME_TimestampNBO start_date;
    1232             :   struct GNUNET_TIME_TimestampNBO end_date;
    1233             :   struct GNUNET_TIME_RelativeNBO wad_frequency;
    1234             :   struct TALER_AmountNBO wad_fee;
    1235             :   struct GNUNET_HashCode h_url;
    1236             : };
    1237             : 
    1238             : GNUNET_NETWORK_STRUCT_END
    1239             : 
    1240             : 
    1241             : void
    1242           0 : TALER_exchange_offline_partner_details_sign (
    1243             :   const struct TALER_MasterPublicKeyP *partner_pub,
    1244             :   struct GNUNET_TIME_Timestamp start_date,
    1245             :   struct GNUNET_TIME_Timestamp end_date,
    1246             :   struct GNUNET_TIME_Relative wad_frequency,
    1247             :   const struct TALER_Amount *wad_fee,
    1248             :   const char *partner_base_url,
    1249             :   const struct TALER_MasterPrivateKeyP *master_priv,
    1250             :   struct TALER_MasterSignatureP *master_sig)
    1251             : {
    1252           0 :   struct TALER_PartnerConfigurationPS wd = {
    1253           0 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_PARTNER_DETAILS),
    1254           0 :     .purpose.size = htonl (sizeof (wd)),
    1255             :     .partner_pub = *partner_pub,
    1256           0 :     .start_date = GNUNET_TIME_timestamp_hton (start_date),
    1257           0 :     .end_date = GNUNET_TIME_timestamp_hton (end_date),
    1258           0 :     .wad_frequency = GNUNET_TIME_relative_hton (wad_frequency),
    1259             :   };
    1260             : 
    1261           0 :   GNUNET_CRYPTO_hash (partner_base_url,
    1262           0 :                       strlen (partner_base_url) + 1,
    1263             :                       &wd.h_url);
    1264           0 :   TALER_amount_hton (&wd.wad_fee,
    1265             :                      wad_fee);
    1266           0 :   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
    1267             :                             &wd,
    1268             :                             &master_sig->eddsa_signature);
    1269           0 : }
    1270             : 
    1271             : 
    1272             : enum GNUNET_GenericReturnValue
    1273           0 : TALER_exchange_offline_partner_details_verify (
    1274             :   const struct TALER_MasterPublicKeyP *partner_pub,
    1275             :   struct GNUNET_TIME_Timestamp start_date,
    1276             :   struct GNUNET_TIME_Timestamp end_date,
    1277             :   struct GNUNET_TIME_Relative wad_frequency,
    1278             :   const struct TALER_Amount *wad_fee,
    1279             :   const char *partner_base_url,
    1280             :   const struct TALER_MasterPublicKeyP *master_pub,
    1281             :   const struct TALER_MasterSignatureP *master_sig)
    1282             : {
    1283           0 :   struct TALER_PartnerConfigurationPS wd = {
    1284           0 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_PARTNER_DETAILS),
    1285           0 :     .purpose.size = htonl (sizeof (wd)),
    1286             :     .partner_pub = *partner_pub,
    1287           0 :     .start_date = GNUNET_TIME_timestamp_hton (start_date),
    1288           0 :     .end_date = GNUNET_TIME_timestamp_hton (end_date),
    1289           0 :     .wad_frequency = GNUNET_TIME_relative_hton (wad_frequency),
    1290             :   };
    1291             : 
    1292           0 :   GNUNET_CRYPTO_hash (partner_base_url,
    1293           0 :                       strlen (partner_base_url) + 1,
    1294             :                       &wd.h_url);
    1295           0 :   TALER_amount_hton (&wd.wad_fee,
    1296             :                      wad_fee);
    1297           0 :   return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_PARTNER_DETAILS,
    1298             :                                      &wd,
    1299             :                                      &master_sig->eddsa_signature,
    1300             :                                      &master_pub->eddsa_pub);
    1301             : }
    1302             : 
    1303             : 
    1304             : GNUNET_NETWORK_STRUCT_BEGIN
    1305             : 
    1306             : /**
    1307             :  * Message signed by account to drain profits
    1308             :  * from the escrow account of the exchange.
    1309             :  */
    1310             : struct TALER_DrainProfitPS
    1311             : {
    1312             : 
    1313             :   /**
    1314             :    * Purpose is #TALER_SIGNATURE_MASTER_DRAIN_PROFITS
    1315             :    */
    1316             :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
    1317             :   struct TALER_WireTransferIdentifierRawP wtid;
    1318             :   struct GNUNET_TIME_TimestampNBO date;
    1319             :   struct TALER_AmountNBO amount;
    1320             :   struct GNUNET_HashCode h_section;
    1321             :   struct TALER_FullPaytoHashP h_payto;
    1322             : };
    1323             : 
    1324             : GNUNET_NETWORK_STRUCT_END
    1325             : 
    1326             : 
    1327             : void
    1328           1 : TALER_exchange_offline_profit_drain_sign (
    1329             :   const struct TALER_WireTransferIdentifierRawP *wtid,
    1330             :   struct GNUNET_TIME_Timestamp date,
    1331             :   const struct TALER_Amount *amount,
    1332             :   const char *account_section,
    1333             :   const struct TALER_FullPayto payto_uri,
    1334             :   const struct TALER_MasterPrivateKeyP *master_priv,
    1335             :   struct TALER_MasterSignatureP *master_sig)
    1336             : {
    1337           1 :   struct TALER_DrainProfitPS wd = {
    1338           1 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_DRAIN_PROFIT),
    1339           1 :     .purpose.size = htonl (sizeof (wd)),
    1340             :     .wtid = *wtid,
    1341           1 :     .date = GNUNET_TIME_timestamp_hton (date),
    1342             :   };
    1343             : 
    1344           1 :   GNUNET_CRYPTO_hash (account_section,
    1345           1 :                       strlen (account_section) + 1,
    1346             :                       &wd.h_section);
    1347           1 :   TALER_full_payto_hash (payto_uri,
    1348             :                          &wd.h_payto);
    1349           1 :   TALER_amount_hton (&wd.amount,
    1350             :                      amount);
    1351           1 :   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
    1352             :                             &wd,
    1353             :                             &master_sig->eddsa_signature);
    1354           1 : }
    1355             : 
    1356             : 
    1357             : enum GNUNET_GenericReturnValue
    1358           3 : TALER_exchange_offline_profit_drain_verify (
    1359             :   const struct TALER_WireTransferIdentifierRawP *wtid,
    1360             :   struct GNUNET_TIME_Timestamp date,
    1361             :   const struct TALER_Amount *amount,
    1362             :   const char *account_section,
    1363             :   const struct TALER_FullPayto payto_uri,
    1364             :   const struct TALER_MasterPublicKeyP *master_pub,
    1365             :   const struct TALER_MasterSignatureP *master_sig)
    1366             : {
    1367           3 :   struct TALER_DrainProfitPS wd = {
    1368           3 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_DRAIN_PROFIT),
    1369           3 :     .purpose.size = htonl (sizeof (wd)),
    1370             :     .wtid = *wtid,
    1371           3 :     .date = GNUNET_TIME_timestamp_hton (date),
    1372             :   };
    1373             : 
    1374           3 :   GNUNET_CRYPTO_hash (account_section,
    1375           3 :                       strlen (account_section) + 1,
    1376             :                       &wd.h_section);
    1377           3 :   TALER_full_payto_hash (payto_uri,
    1378             :                          &wd.h_payto);
    1379           3 :   TALER_amount_hton (&wd.amount,
    1380             :                      amount);
    1381           3 :   return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_DRAIN_PROFIT,
    1382             :                                      &wd,
    1383             :                                      &master_sig->eddsa_signature,
    1384             :                                      &master_pub->eddsa_pub);
    1385             : }
    1386             : 
    1387             : 
    1388             : /* end of offline_signatures.c */

Generated by: LCOV version 1.16