LCOV - code coverage report
Current view: top level - util - offline_signatures.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 69.7 % 274 191
Test Date: 2026-01-04 22:17:00 Functions: 66.7 % 30 20

            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           57 : 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          114 :   struct TALER_ExchangeSigningKeyValidityPS skv = {
     455           57 :     .purpose.purpose = htonl (
     456              :       TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY),
     457           57 :     .purpose.size = htonl (sizeof (skv)),
     458           57 :     .start = GNUNET_TIME_timestamp_hton (start_sign),
     459           57 :     .expire = GNUNET_TIME_timestamp_hton (end_sign),
     460           57 :     .end = GNUNET_TIME_timestamp_hton (end_legal),
     461              :     .signkey_pub = *exchange_pub
     462              :   };
     463              : 
     464           57 :   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
     465              :                             &skv,
     466              :                             &master_sig->eddsa_signature);
     467           57 : }
     468              : 
     469              : 
     470              : enum GNUNET_GenericReturnValue
     471          253 : 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          506 :   struct TALER_ExchangeSigningKeyValidityPS skv = {
     480          253 :     .purpose.purpose = htonl (
     481              :       TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY),
     482          253 :     .purpose.size = htonl (sizeof (skv)),
     483          253 :     .start = GNUNET_TIME_timestamp_hton (start_sign),
     484          253 :     .expire = GNUNET_TIME_timestamp_hton (end_sign),
     485          253 :     .end = GNUNET_TIME_timestamp_hton (end_legal),
     486              :     .signkey_pub = *exchange_pub
     487              :   };
     488              : 
     489              :   return
     490          253 :     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         5373 : 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        10746 :   struct TALER_DenominationKeyValidityPS issue = {
     596              :     .purpose.purpose
     597         5373 :       = htonl (TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY),
     598              :     .purpose.size
     599         5373 :       = htonl (sizeof (issue)),
     600         5373 :     .start = GNUNET_TIME_timestamp_hton (stamp_start),
     601         5373 :     .expire_withdraw = GNUNET_TIME_timestamp_hton (stamp_expire_withdraw),
     602         5373 :     .expire_deposit = GNUNET_TIME_timestamp_hton (stamp_expire_deposit),
     603         5373 :     .expire_legal = GNUNET_TIME_timestamp_hton (stamp_expire_legal),
     604              :     .denom_hash = *h_denom_pub
     605              :   };
     606              : 
     607         5373 :   GNUNET_CRYPTO_eddsa_key_get_public (&master_priv->eddsa_priv,
     608              :                                       &issue.master.eddsa_pub);
     609         5373 :   TALER_amount_hton (&issue.value,
     610              :                      coin_value);
     611         5373 :   TALER_denom_fee_set_hton (&issue.fees,
     612              :                             fees);
     613         5373 :   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
     614              :                             &issue,
     615              :                             &master_sig->eddsa_signature);
     616         5373 : }
     617              : 
     618              : 
     619              : enum GNUNET_GenericReturnValue
     620        25706 : 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        51412 :   struct TALER_DenominationKeyValidityPS dkv = {
     632        25706 :     .purpose.purpose = htonl (
     633              :       TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY),
     634        25706 :     .purpose.size = htonl (sizeof (dkv)),
     635              :     .master = *master_pub,
     636        25706 :     .start = GNUNET_TIME_timestamp_hton (stamp_start),
     637        25706 :     .expire_withdraw = GNUNET_TIME_timestamp_hton (stamp_expire_withdraw),
     638        25706 :     .expire_deposit = GNUNET_TIME_timestamp_hton (stamp_expire_deposit),
     639        25706 :     .expire_legal = GNUNET_TIME_timestamp_hton (stamp_expire_legal),
     640              :     .denom_hash = *h_denom_pub
     641              :   };
     642              : 
     643        25706 :   TALER_amount_hton (&dkv.value,
     644              :                      coin_value);
     645        25706 :   TALER_denom_fee_set_hton (&dkv.fees,
     646              :                             fees);
     647              :   return
     648        25706 :     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 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           23 : 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           23 :   struct TALER_MasterAddWirePS kv = {
     712           23 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_ADD_WIRE),
     713           23 :     .purpose.size = htonl (sizeof (kv)),
     714           23 :     .start_date = GNUNET_TIME_timestamp_hton (now),
     715              :   };
     716              : 
     717           23 :   TALER_full_payto_hash (payto_uri,
     718              :                          &kv.h_payto);
     719           23 :   if (NULL != conversion_url)
     720            0 :     GNUNET_CRYPTO_hash (conversion_url,
     721            0 :                         strlen (conversion_url) + 1,
     722              :                         &kv.h_conversion_url);
     723           23 :   TALER_json_hash (debit_restrictions,
     724              :                    &kv.h_debit_restrictions);
     725           23 :   TALER_json_hash (credit_restrictions,
     726              :                    &kv.h_credit_restrictions);
     727           23 :   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
     728              :                             &kv,
     729              :                             &master_sig->eddsa_signature);
     730           23 : }
     731              : 
     732              : 
     733              : enum GNUNET_GenericReturnValue
     734           25 : 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           25 :   struct TALER_MasterAddWirePS aw = {
     744           25 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_ADD_WIRE),
     745           25 :     .purpose.size = htonl (sizeof (aw)),
     746           25 :     .start_date = GNUNET_TIME_timestamp_hton (sign_time),
     747              :   };
     748              : 
     749           25 :   TALER_full_payto_hash (payto_uri,
     750              :                          &aw.h_payto);
     751           25 :   if (NULL != conversion_url)
     752            0 :     GNUNET_CRYPTO_hash (conversion_url,
     753            0 :                         strlen (conversion_url) + 1,
     754              :                         &aw.h_conversion_url);
     755           25 :   TALER_json_hash (debit_restrictions,
     756              :                    &aw.h_debit_restrictions);
     757           25 :   TALER_json_hash (credit_restrictions,
     758              :                    &aw.h_credit_restrictions);
     759              :   return
     760           25 :     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_SignaturePurpose 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_SignaturePurpose 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           42 : 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           42 :   struct TALER_MasterWireFeePS kv = {
     895           42 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_WIRE_FEES),
     896           42 :     .purpose.size = htonl (sizeof (kv)),
     897           42 :     .start_date = GNUNET_TIME_timestamp_hton (start_time),
     898           42 :     .end_date = GNUNET_TIME_timestamp_hton (end_time),
     899              :   };
     900              : 
     901           42 :   GNUNET_CRYPTO_hash (payment_method,
     902           42 :                       strlen (payment_method) + 1,
     903              :                       &kv.h_wire_method);
     904           42 :   TALER_wire_fee_set_hton (&kv.fees,
     905              :                            fees);
     906           42 :   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
     907              :                             &kv,
     908              :                             &master_sig->eddsa_signature);
     909           42 : }
     910              : 
     911              : 
     912              : enum GNUNET_GenericReturnValue
     913          166 : 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          166 :   struct TALER_MasterWireFeePS wf = {
     922          166 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_WIRE_FEES),
     923          166 :     .purpose.size = htonl (sizeof (wf)),
     924          166 :     .start_date = GNUNET_TIME_timestamp_hton (start_time),
     925          166 :     .end_date = GNUNET_TIME_timestamp_hton (end_time)
     926              :   };
     927              : 
     928          166 :   GNUNET_CRYPTO_hash (payment_method,
     929          166 :                       strlen (payment_method) + 1,
     930              :                       &wf.h_wire_method);
     931          166 :   TALER_wire_fee_set_hton (&wf.fees,
     932              :                            fees);
     933              :   return
     934          166 :     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_SignaturePurpose 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           34 : 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           68 :   struct TALER_MasterGlobalFeePS wf = {
    1009           34 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_GLOBAL_FEES),
    1010           34 :     .purpose.size = htonl (sizeof (wf)),
    1011           34 :     .start_date = GNUNET_TIME_timestamp_hton (start_time),
    1012           34 :     .end_date = GNUNET_TIME_timestamp_hton (end_time),
    1013           34 :     .purse_timeout = GNUNET_TIME_relative_hton (purse_timeout),
    1014           34 :     .history_expiration = GNUNET_TIME_relative_hton (history_expiration),
    1015           34 :     .purse_account_limit = htonl (purse_account_limit)
    1016              :   };
    1017              : 
    1018           34 :   TALER_global_fee_set_hton (&wf.fees,
    1019              :                              fees);
    1020           34 :   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
    1021              :                             &wf,
    1022              :                             &master_sig->eddsa_signature);
    1023           34 : }
    1024              : 
    1025              : 
    1026              : enum GNUNET_GenericReturnValue
    1027          158 : 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          316 :   struct TALER_MasterGlobalFeePS wf = {
    1038          158 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_GLOBAL_FEES),
    1039          158 :     .purpose.size = htonl (sizeof (wf)),
    1040          158 :     .start_date = GNUNET_TIME_timestamp_hton (start_time),
    1041          158 :     .end_date = GNUNET_TIME_timestamp_hton (end_time),
    1042          158 :     .purse_timeout = GNUNET_TIME_relative_hton (purse_timeout),
    1043          158 :     .history_expiration = GNUNET_TIME_relative_hton (history_expiration),
    1044          158 :     .purse_account_limit = htonl (purse_account_limit)
    1045              :   };
    1046              : 
    1047          158 :   TALER_global_fee_set_hton (&wf.fees,
    1048              :                              fees);
    1049              :   return
    1050          158 :     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_SignaturePurpose 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_SignaturePurpose 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           93 : 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           93 :   struct TALER_MasterWireDetailsPS wd = {
    1167           93 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_WIRE_DETAILS),
    1168           93 :     .purpose.size = htonl (sizeof (wd))
    1169              :   };
    1170              : 
    1171           93 :   TALER_full_payto_hash (payto_uri,
    1172              :                          &wd.h_wire_details);
    1173           93 :   if (NULL != conversion_url)
    1174            1 :     GNUNET_CRYPTO_hash (conversion_url,
    1175            1 :                         strlen (conversion_url) + 1,
    1176              :                         &wd.h_conversion_url);
    1177           93 :   TALER_json_hash (debit_restrictions,
    1178              :                    &wd.h_debit_restrictions);
    1179           93 :   TALER_json_hash (credit_restrictions,
    1180              :                    &wd.h_credit_restrictions);
    1181           93 :   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           24 : 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           24 :   struct TALER_MasterWireDetailsPS wd = {
    1198           24 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_WIRE_DETAILS),
    1199           24 :     .purpose.size = htonl (sizeof (wd))
    1200              :   };
    1201              : 
    1202           24 :   TALER_full_payto_hash (payto_uri,
    1203              :                          &wd.h_wire_details);
    1204           24 :   if (NULL != conversion_url)
    1205            0 :     GNUNET_CRYPTO_hash (conversion_url,
    1206            0 :                         strlen (conversion_url) + 1,
    1207              :                         &wd.h_conversion_url);
    1208           24 :   TALER_json_hash (debit_restrictions,
    1209              :                    &wd.h_debit_restrictions);
    1210           24 :   TALER_json_hash (credit_restrictions,
    1211              :                    &wd.h_credit_restrictions);
    1212           24 :   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
    1213              :                             &wd,
    1214              :                             &master_sig->eddsa_signature);
    1215           24 : }
    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_SignaturePurpose 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_SignaturePurpose 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            0 : 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            0 :   struct TALER_DrainProfitPS wd = {
    1338            0 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_DRAIN_PROFIT),
    1339            0 :     .purpose.size = htonl (sizeof (wd)),
    1340              :     .wtid = *wtid,
    1341            0 :     .date = GNUNET_TIME_timestamp_hton (date),
    1342              :   };
    1343              : 
    1344            0 :   GNUNET_CRYPTO_hash (account_section,
    1345            0 :                       strlen (account_section) + 1,
    1346              :                       &wd.h_section);
    1347            0 :   TALER_full_payto_hash (payto_uri,
    1348              :                          &wd.h_payto);
    1349            0 :   TALER_amount_hton (&wd.amount,
    1350              :                      amount);
    1351            0 :   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
    1352              :                             &wd,
    1353              :                             &master_sig->eddsa_signature);
    1354            0 : }
    1355              : 
    1356              : 
    1357              : enum GNUNET_GenericReturnValue
    1358            0 : 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            0 :   struct TALER_DrainProfitPS wd = {
    1368            0 :     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_DRAIN_PROFIT),
    1369            0 :     .purpose.size = htonl (sizeof (wd)),
    1370              :     .wtid = *wtid,
    1371            0 :     .date = GNUNET_TIME_timestamp_hton (date),
    1372              :   };
    1373              : 
    1374            0 :   GNUNET_CRYPTO_hash (account_section,
    1375            0 :                       strlen (account_section) + 1,
    1376              :                       &wd.h_section);
    1377            0 :   TALER_full_payto_hash (payto_uri,
    1378              :                          &wd.h_payto);
    1379            0 :   TALER_amount_hton (&wd.amount,
    1380              :                      amount);
    1381            0 :   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 2.0-1