exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

offline_signatures.c (42090B)


      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 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   struct TALER_MasterAmlOfficerStatusPS as = {
     75     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_AML_KEY),
     76     .purpose.size = htonl (sizeof (as)),
     77     .change_date = GNUNET_TIME_timestamp_hton (change_date),
     78     .officer_pub = *officer_pub,
     79     .is_active = htonl ((is_active ? 1 : 0) + (read_only ? 2 : 0))
     80   };
     81 
     82   GNUNET_CRYPTO_hash (officer_name,
     83                       strlen (officer_name) + 1,
     84                       &as.h_officer_name);
     85   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
     86                             &as,
     87                             &master_sig->eddsa_signature);
     88 }
     89 
     90 
     91 enum GNUNET_GenericReturnValue
     92 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   struct TALER_MasterAmlOfficerStatusPS as = {
    102     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_AML_KEY),
    103     .purpose.size = htonl (sizeof (as)),
    104     .change_date = GNUNET_TIME_timestamp_hton (change_date),
    105     .officer_pub = *officer_pub,
    106     .is_active = htonl ((is_active ? 1 : 0) + (read_only ? 2 : 0))
    107   };
    108 
    109   GNUNET_CRYPTO_hash (officer_name,
    110                       strlen (officer_name) + 1,
    111                       &as.h_officer_name);
    112   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 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   struct TALER_MasterAddAuditorPS kv = {
    161     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_ADD_AUDITOR),
    162     .purpose.size = htonl (sizeof (kv)),
    163     .start_date = GNUNET_TIME_timestamp_hton (start_date),
    164     .auditor_pub = *auditor_pub,
    165   };
    166 
    167   GNUNET_CRYPTO_hash (auditor_url,
    168                       strlen (auditor_url) + 1,
    169                       &kv.h_auditor_url);
    170   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
    171                             &kv,
    172                             &master_sig->eddsa_signature);
    173 }
    174 
    175 
    176 enum GNUNET_GenericReturnValue
    177 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   struct TALER_MasterAddAuditorPS aa = {
    185     .purpose.purpose = htonl (
    186       TALER_SIGNATURE_MASTER_ADD_AUDITOR),
    187     .purpose.size = htonl (sizeof (aa)),
    188     .start_date = GNUNET_TIME_timestamp_hton (start_date),
    189     .auditor_pub = *auditor_pub
    190   };
    191 
    192   GNUNET_CRYPTO_hash (auditor_url,
    193                       strlen (auditor_url) + 1,
    194                       &aa.h_auditor_url);
    195   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 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   struct TALER_MasterDelAuditorPS kv = {
    239     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_DEL_AUDITOR),
    240     .purpose.size = htonl (sizeof (kv)),
    241     .end_date = GNUNET_TIME_timestamp_hton (end_date),
    242     .auditor_pub = *auditor_pub,
    243   };
    244 
    245   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
    246                             &kv,
    247                             &master_sig->eddsa_signature);
    248 }
    249 
    250 
    251 enum GNUNET_GenericReturnValue
    252 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   struct TALER_MasterDelAuditorPS da = {
    259     .purpose.purpose = htonl (
    260       TALER_SIGNATURE_MASTER_DEL_AUDITOR),
    261     .purpose.size = htonl (sizeof (da)),
    262     .end_date = GNUNET_TIME_timestamp_hton (end_date),
    263     .auditor_pub = *auditor_pub
    264   };
    265 
    266   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 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   struct TALER_MasterDenominationKeyRevocationPS rm = {
    302     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED),
    303     .purpose.size = htonl (sizeof (rm)),
    304     .h_denom_pub = *h_denom_pub
    305   };
    306 
    307   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
    308                             &rm,
    309                             &master_sig->eddsa_signature);
    310 }
    311 
    312 
    313 enum GNUNET_GenericReturnValue
    314 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   struct TALER_MasterDenominationKeyRevocationPS kr = {
    320     .purpose.purpose = htonl (
    321       TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED),
    322     .purpose.size = htonl (sizeof (kr)),
    323     .h_denom_pub = *h_denom_pub
    324   };
    325 
    326   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 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   struct TALER_MasterSigningKeyRevocationPS kv = {
    363     .purpose.purpose = htonl (
    364       TALER_SIGNATURE_MASTER_SIGNING_KEY_REVOKED),
    365     .purpose.size = htonl (sizeof (kv)),
    366     .exchange_pub = *exchange_pub
    367   };
    368 
    369   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
    370                             &kv,
    371                             &master_sig->eddsa_signature);
    372 }
    373 
    374 
    375 enum GNUNET_GenericReturnValue
    376 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   struct TALER_MasterSigningKeyRevocationPS rm = {
    382     .purpose.purpose = htonl (
    383       TALER_SIGNATURE_MASTER_SIGNING_KEY_REVOKED),
    384     .purpose.size = htonl (sizeof (rm)),
    385     .exchange_pub = *exchange_pub
    386   };
    387 
    388   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 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   struct TALER_ExchangeSigningKeyValidityPS skv = {
    455     .purpose.purpose = htonl (
    456       TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY),
    457     .purpose.size = htonl (sizeof (skv)),
    458     .start = GNUNET_TIME_timestamp_hton (start_sign),
    459     .expire = GNUNET_TIME_timestamp_hton (end_sign),
    460     .end = GNUNET_TIME_timestamp_hton (end_legal),
    461     .signkey_pub = *exchange_pub
    462   };
    463 
    464   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
    465                             &skv,
    466                             &master_sig->eddsa_signature);
    467 }
    468 
    469 
    470 enum GNUNET_GenericReturnValue
    471 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   struct TALER_ExchangeSigningKeyValidityPS skv = {
    480     .purpose.purpose = htonl (
    481       TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY),
    482     .purpose.size = htonl (sizeof (skv)),
    483     .start = GNUNET_TIME_timestamp_hton (start_sign),
    484     .expire = GNUNET_TIME_timestamp_hton (end_sign),
    485     .end = GNUNET_TIME_timestamp_hton (end_legal),
    486     .signkey_pub = *exchange_pub
    487   };
    488 
    489   return
    490     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 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   struct TALER_DenominationKeyValidityPS issue = {
    596     .purpose.purpose
    597       = htonl (TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY),
    598     .purpose.size
    599       = htonl (sizeof (issue)),
    600     .start = GNUNET_TIME_timestamp_hton (stamp_start),
    601     .expire_withdraw = GNUNET_TIME_timestamp_hton (stamp_expire_withdraw),
    602     .expire_deposit = GNUNET_TIME_timestamp_hton (stamp_expire_deposit),
    603     .expire_legal = GNUNET_TIME_timestamp_hton (stamp_expire_legal),
    604     .denom_hash = *h_denom_pub
    605   };
    606 
    607   GNUNET_CRYPTO_eddsa_key_get_public (&master_priv->eddsa_priv,
    608                                       &issue.master.eddsa_pub);
    609   TALER_amount_hton (&issue.value,
    610                      coin_value);
    611   TALER_denom_fee_set_hton (&issue.fees,
    612                             fees);
    613   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
    614                             &issue,
    615                             &master_sig->eddsa_signature);
    616 }
    617 
    618 
    619 enum GNUNET_GenericReturnValue
    620 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   struct TALER_DenominationKeyValidityPS dkv = {
    632     .purpose.purpose = htonl (
    633       TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY),
    634     .purpose.size = htonl (sizeof (dkv)),
    635     .master = *master_pub,
    636     .start = GNUNET_TIME_timestamp_hton (stamp_start),
    637     .expire_withdraw = GNUNET_TIME_timestamp_hton (stamp_expire_withdraw),
    638     .expire_deposit = GNUNET_TIME_timestamp_hton (stamp_expire_deposit),
    639     .expire_legal = GNUNET_TIME_timestamp_hton (stamp_expire_legal),
    640     .denom_hash = *h_denom_pub
    641   };
    642 
    643   TALER_amount_hton (&dkv.value,
    644                      coin_value);
    645   TALER_denom_fee_set_hton (&dkv.fees,
    646                             fees);
    647   return
    648     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 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   struct TALER_MasterAddWirePS kv = {
    712     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_ADD_WIRE),
    713     .purpose.size = htonl (sizeof (kv)),
    714     .start_date = GNUNET_TIME_timestamp_hton (now),
    715   };
    716 
    717   TALER_full_payto_hash (payto_uri,
    718                          &kv.h_payto);
    719   if (NULL != conversion_url)
    720     GNUNET_CRYPTO_hash (conversion_url,
    721                         strlen (conversion_url) + 1,
    722                         &kv.h_conversion_url);
    723   TALER_json_hash (debit_restrictions,
    724                    &kv.h_debit_restrictions);
    725   TALER_json_hash (credit_restrictions,
    726                    &kv.h_credit_restrictions);
    727   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
    728                             &kv,
    729                             &master_sig->eddsa_signature);
    730 }
    731 
    732 
    733 enum GNUNET_GenericReturnValue
    734 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   struct TALER_MasterAddWirePS aw = {
    744     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_ADD_WIRE),
    745     .purpose.size = htonl (sizeof (aw)),
    746     .start_date = GNUNET_TIME_timestamp_hton (sign_time),
    747   };
    748 
    749   TALER_full_payto_hash (payto_uri,
    750                          &aw.h_payto);
    751   if (NULL != conversion_url)
    752     GNUNET_CRYPTO_hash (conversion_url,
    753                         strlen (conversion_url) + 1,
    754                         &aw.h_conversion_url);
    755   TALER_json_hash (debit_restrictions,
    756                    &aw.h_debit_restrictions);
    757   TALER_json_hash (credit_restrictions,
    758                    &aw.h_credit_restrictions);
    759   return
    760     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 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   struct TALER_MasterDelWirePS kv = {
    806     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_DEL_WIRE),
    807     .purpose.size = htonl (sizeof (kv)),
    808     .end_date = GNUNET_TIME_timestamp_hton (now),
    809   };
    810 
    811   TALER_full_payto_hash (payto_uri,
    812                          &kv.h_payto);
    813   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
    814                             &kv,
    815                             &master_sig->eddsa_signature);
    816 }
    817 
    818 
    819 enum GNUNET_GenericReturnValue
    820 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   struct TALER_MasterDelWirePS aw = {
    827     .purpose.purpose = htonl (
    828       TALER_SIGNATURE_MASTER_DEL_WIRE),
    829     .purpose.size = htonl (sizeof (aw)),
    830     .end_date = GNUNET_TIME_timestamp_hton (sign_time),
    831   };
    832 
    833   TALER_full_payto_hash (payto_uri,
    834                          &aw.h_payto);
    835   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 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   struct TALER_MasterWireFeePS kv = {
    895     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_WIRE_FEES),
    896     .purpose.size = htonl (sizeof (kv)),
    897     .start_date = GNUNET_TIME_timestamp_hton (start_time),
    898     .end_date = GNUNET_TIME_timestamp_hton (end_time),
    899   };
    900 
    901   GNUNET_CRYPTO_hash (payment_method,
    902                       strlen (payment_method) + 1,
    903                       &kv.h_wire_method);
    904   TALER_wire_fee_set_hton (&kv.fees,
    905                            fees);
    906   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
    907                             &kv,
    908                             &master_sig->eddsa_signature);
    909 }
    910 
    911 
    912 enum GNUNET_GenericReturnValue
    913 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   struct TALER_MasterWireFeePS wf = {
    922     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_WIRE_FEES),
    923     .purpose.size = htonl (sizeof (wf)),
    924     .start_date = GNUNET_TIME_timestamp_hton (start_time),
    925     .end_date = GNUNET_TIME_timestamp_hton (end_time)
    926   };
    927 
    928   GNUNET_CRYPTO_hash (payment_method,
    929                       strlen (payment_method) + 1,
    930                       &wf.h_wire_method);
    931   TALER_wire_fee_set_hton (&wf.fees,
    932                            fees);
    933   return
    934     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 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   struct TALER_MasterGlobalFeePS wf = {
   1009     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_GLOBAL_FEES),
   1010     .purpose.size = htonl (sizeof (wf)),
   1011     .start_date = GNUNET_TIME_timestamp_hton (start_time),
   1012     .end_date = GNUNET_TIME_timestamp_hton (end_time),
   1013     .purse_timeout = GNUNET_TIME_relative_hton (purse_timeout),
   1014     .history_expiration = GNUNET_TIME_relative_hton (history_expiration),
   1015     .purse_account_limit = htonl (purse_account_limit)
   1016   };
   1017 
   1018   TALER_global_fee_set_hton (&wf.fees,
   1019                              fees);
   1020   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
   1021                             &wf,
   1022                             &master_sig->eddsa_signature);
   1023 }
   1024 
   1025 
   1026 enum GNUNET_GenericReturnValue
   1027 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   struct TALER_MasterGlobalFeePS wf = {
   1038     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_GLOBAL_FEES),
   1039     .purpose.size = htonl (sizeof (wf)),
   1040     .start_date = GNUNET_TIME_timestamp_hton (start_time),
   1041     .end_date = GNUNET_TIME_timestamp_hton (end_time),
   1042     .purse_timeout = GNUNET_TIME_relative_hton (purse_timeout),
   1043     .history_expiration = GNUNET_TIME_relative_hton (history_expiration),
   1044     .purse_account_limit = htonl (purse_account_limit)
   1045   };
   1046 
   1047   TALER_global_fee_set_hton (&wf.fees,
   1048                              fees);
   1049   return
   1050     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 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   struct TALER_MasterExtensionManifestPS ec = {
   1087     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_EXTENSION),
   1088     .purpose.size = htonl (sizeof(ec)),
   1089     .h_manifest = *h_manifest
   1090   };
   1091   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
   1092                             &ec,
   1093                             &master_sig->eddsa_signature);
   1094 }
   1095 
   1096 
   1097 enum GNUNET_GenericReturnValue
   1098 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   struct TALER_MasterExtensionManifestPS ec = {
   1105     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_EXTENSION),
   1106     .purpose.size = htonl (sizeof(ec)),
   1107     .h_manifest = *h_manifest
   1108   };
   1109 
   1110   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 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   struct TALER_MasterWireDetailsPS wd = {
   1167     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_WIRE_DETAILS),
   1168     .purpose.size = htonl (sizeof (wd))
   1169   };
   1170 
   1171   TALER_full_payto_hash (payto_uri,
   1172                          &wd.h_wire_details);
   1173   if (NULL != conversion_url)
   1174     GNUNET_CRYPTO_hash (conversion_url,
   1175                         strlen (conversion_url) + 1,
   1176                         &wd.h_conversion_url);
   1177   TALER_json_hash (debit_restrictions,
   1178                    &wd.h_debit_restrictions);
   1179   TALER_json_hash (credit_restrictions,
   1180                    &wd.h_credit_restrictions);
   1181   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 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   struct TALER_MasterWireDetailsPS wd = {
   1198     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_WIRE_DETAILS),
   1199     .purpose.size = htonl (sizeof (wd))
   1200   };
   1201 
   1202   TALER_full_payto_hash (payto_uri,
   1203                          &wd.h_wire_details);
   1204   if (NULL != conversion_url)
   1205     GNUNET_CRYPTO_hash (conversion_url,
   1206                         strlen (conversion_url) + 1,
   1207                         &wd.h_conversion_url);
   1208   TALER_json_hash (debit_restrictions,
   1209                    &wd.h_debit_restrictions);
   1210   TALER_json_hash (credit_restrictions,
   1211                    &wd.h_credit_restrictions);
   1212   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
   1213                             &wd,
   1214                             &master_sig->eddsa_signature);
   1215 }
   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 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   struct TALER_PartnerConfigurationPS wd = {
   1253     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_PARTNER_DETAILS),
   1254     .purpose.size = htonl (sizeof (wd)),
   1255     .partner_pub = *partner_pub,
   1256     .start_date = GNUNET_TIME_timestamp_hton (start_date),
   1257     .end_date = GNUNET_TIME_timestamp_hton (end_date),
   1258     .wad_frequency = GNUNET_TIME_relative_hton (wad_frequency),
   1259   };
   1260 
   1261   GNUNET_CRYPTO_hash (partner_base_url,
   1262                       strlen (partner_base_url) + 1,
   1263                       &wd.h_url);
   1264   TALER_amount_hton (&wd.wad_fee,
   1265                      wad_fee);
   1266   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
   1267                             &wd,
   1268                             &master_sig->eddsa_signature);
   1269 }
   1270 
   1271 
   1272 enum GNUNET_GenericReturnValue
   1273 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   struct TALER_PartnerConfigurationPS wd = {
   1284     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_PARTNER_DETAILS),
   1285     .purpose.size = htonl (sizeof (wd)),
   1286     .partner_pub = *partner_pub,
   1287     .start_date = GNUNET_TIME_timestamp_hton (start_date),
   1288     .end_date = GNUNET_TIME_timestamp_hton (end_date),
   1289     .wad_frequency = GNUNET_TIME_relative_hton (wad_frequency),
   1290   };
   1291 
   1292   GNUNET_CRYPTO_hash (partner_base_url,
   1293                       strlen (partner_base_url) + 1,
   1294                       &wd.h_url);
   1295   TALER_amount_hton (&wd.wad_fee,
   1296                      wad_fee);
   1297   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 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   struct TALER_DrainProfitPS wd = {
   1338     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_DRAIN_PROFIT),
   1339     .purpose.size = htonl (sizeof (wd)),
   1340     .wtid = *wtid,
   1341     .date = GNUNET_TIME_timestamp_hton (date),
   1342   };
   1343 
   1344   GNUNET_CRYPTO_hash (account_section,
   1345                       strlen (account_section) + 1,
   1346                       &wd.h_section);
   1347   TALER_full_payto_hash (payto_uri,
   1348                          &wd.h_payto);
   1349   TALER_amount_hton (&wd.amount,
   1350                      amount);
   1351   GNUNET_CRYPTO_eddsa_sign (&master_priv->eddsa_priv,
   1352                             &wd,
   1353                             &master_sig->eddsa_signature);
   1354 }
   1355 
   1356 
   1357 enum GNUNET_GenericReturnValue
   1358 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   struct TALER_DrainProfitPS wd = {
   1368     .purpose.purpose = htonl (TALER_SIGNATURE_MASTER_DRAIN_PROFIT),
   1369     .purpose.size = htonl (sizeof (wd)),
   1370     .wtid = *wtid,
   1371     .date = GNUNET_TIME_timestamp_hton (date),
   1372   };
   1373 
   1374   GNUNET_CRYPTO_hash (account_section,
   1375                       strlen (account_section) + 1,
   1376                       &wd.h_section);
   1377   TALER_full_payto_hash (payto_uri,
   1378                          &wd.h_payto);
   1379   TALER_amount_hton (&wd.amount,
   1380                      amount);
   1381   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 */