gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-exchange] branch master updated (21551bb4 -> 9e3fb230)


From: gnunet
Subject: [taler-exchange] branch master updated (21551bb4 -> 9e3fb230)
Date: Fri, 01 Jul 2022 07:22:40 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a change to branch master
in repository exchange.

    from 21551bb4 -also add public key for auditor for revoke-basedb.conf
     new 085e40bc -exchange_api_batch_deposit.c compiles
     new 9e3fb230 -gana merge

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 doc/prebuilt                                       |   2 +-
 src/auditor/taler-helper-auditor-reserves.c        |   4 +-
 src/exchange/taler-exchange-httpd_common_deposit.c |   6 +-
 src/exchange/taler-exchange-httpd_keys.c           |   4 +-
 src/exchange/taler-exchange-httpd_purses_create.c  |   4 +-
 src/exchange/taler-exchange-httpd_wire.c           |   4 +-
 src/include/taler_exchange_service.h               | 138 +++++++
 src/include/taler_testing_lib.h                    |  26 ++
 src/lib/Makefile.am                                |   1 +
 ..._api_deposit.c => exchange_api_batch_deposit.c} | 421 +++++++++++----------
 src/lib/exchange_api_common.c                      |  62 +++
 src/lib/exchange_api_common.h                      |  20 +
 src/lib/exchange_api_deposit.c                     |  81 +---
 src/lib/exchange_api_handle.c                      |   2 +-
 src/lib/exchange_api_purse_create_with_deposit.c   |   4 +-
 src/lib/exchange_api_purse_create_with_merge.c     |   4 +-
 16 files changed, 488 insertions(+), 295 deletions(-)
 copy src/lib/{exchange_api_deposit.c => exchange_api_batch_deposit.c} (61%)

diff --git a/doc/prebuilt b/doc/prebuilt
index 1ed97b23..74d9c44e 160000
--- a/doc/prebuilt
+++ b/doc/prebuilt
@@ -1 +1 @@
-Subproject commit 1ed97b23f19c80fa84b21a5eb0c686d5491e8ec6
+Subproject commit 74d9c44ebc257a3d8b9c2c0a806508bd0cc5269a
diff --git a/src/auditor/taler-helper-auditor-reserves.c 
b/src/auditor/taler-helper-auditor-reserves.c
index 54d3db7c..c6c4d3ad 100644
--- a/src/auditor/taler-helper-auditor-reserves.c
+++ b/src/auditor/taler-helper-auditor-reserves.c
@@ -1283,8 +1283,8 @@ handle_purse_deposits (
   struct ReserveContext *rc = cls;
   const char *base_url
     = (NULL == deposit->exchange_base_url)
-    ? TALER_ARL_exchange_url
-    : deposit->exchange_base_url;
+      ? TALER_ARL_exchange_url
+      : deposit->exchange_base_url;
   enum GNUNET_DB_QueryStatus qs;
   struct TALER_Amount amount_minus_fee;
   struct TALER_Amount new_balance;
diff --git a/src/exchange/taler-exchange-httpd_common_deposit.c 
b/src/exchange/taler-exchange-httpd_common_deposit.c
index 7e977420..92e2469f 100644
--- a/src/exchange/taler-exchange-httpd_common_deposit.c
+++ b/src/exchange/taler-exchange-httpd_common_deposit.c
@@ -214,8 +214,8 @@ TEH_common_deposit_check_purse_deposit (
                                         MHD_HTTP_FORBIDDEN,
                                         
TALER_EC_EXCHANGE_PURSE_DEPOSIT_COIN_SIGNATURE_INVALID,
                                         TEH_base_url))
-      ? GNUNET_NO
-      : GNUNET_SYSERR;
+           ? GNUNET_NO
+           : GNUNET_SYSERR;
   }
 
   /* Check and verify the age restriction. */
@@ -301,7 +301,7 @@ if (0 >
                                         MHD_HTTP_INTERNAL_SERVER_ERROR,
                                         TALER_EC_GENERIC_DB_COMMIT_FAILED,
                                         "make_coin_known"))
-             ? GNUNET_NO : GNUNET_SYSERR;
+           ? GNUNET_NO : GNUNET_SYSERR;
   }
   if (qs < 0)
     return (MHD_YES == mhd_ret) ? GNUNET_NO : GNUNET_SYSERR;
diff --git a/src/exchange/taler-exchange-httpd_keys.c 
b/src/exchange/taler-exchange-httpd_keys.c
index 65fe0f31..b1fa2cbc 100644
--- a/src/exchange/taler-exchange-httpd_keys.c
+++ b/src/exchange/taler-exchange-httpd_keys.c
@@ -2216,10 +2216,10 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
           switch (meta.cipher)
           {
           case TALER_DENOMINATION_RSA:
-            cipher = age_restricted ? "RSA+age_restricted": "RSA";
+            cipher = age_restricted ? "RSA+age_restricted" : "RSA";
             break;
           case TALER_DENOMINATION_CS:
-            cipher = age_restricted ? "CS+age_restricted": "CS";
+            cipher = age_restricted ? "CS+age_restricted" : "CS";
             break;
           default:
             GNUNET_assert (false);
diff --git a/src/exchange/taler-exchange-httpd_purses_create.c 
b/src/exchange/taler-exchange-httpd_purses_create.c
index b6eea05f..9cabdb1a 100644
--- a/src/exchange/taler-exchange-httpd_purses_create.c
+++ b/src/exchange/taler-exchange-httpd_purses_create.c
@@ -458,8 +458,8 @@ parse_coin (struct MHD_Connection *connection,
                                         MHD_HTTP_INTERNAL_SERVER_ERROR,
                                         TALER_EC_GENERIC_FAILED_COMPUTE_AMOUNT,
                                         "total deposit contribution"))
-      ? GNUNET_NO
-      : GNUNET_SYSERR;
+           ? GNUNET_NO
+           : GNUNET_SYSERR;
   }
   return GNUNET_OK;
 }
diff --git a/src/exchange/taler-exchange-httpd_wire.c 
b/src/exchange/taler-exchange-httpd_wire.c
index fbc3d5e6..7e5f0a91 100644
--- a/src/exchange/taler-exchange-httpd_wire.c
+++ b/src/exchange/taler-exchange-httpd_wire.c
@@ -400,8 +400,8 @@ build_wire_state (void)
         wsh->http_status = MHD_HTTP_INTERNAL_SERVER_ERROR;
         wsh->wire_reply
           = TALER_MHD_make_error (
-          TALER_EC_EXCHANGE_WIRE_INVALID_PAYTO_CONFIGURED,
-          payto_uri);
+              TALER_EC_EXCHANGE_WIRE_INVALID_PAYTO_CONFIGURED,
+              payto_uri);
         json_decref (wire_accounts_array);
         json_decref (wire_fee_object);
         GNUNET_CRYPTO_hash_context_abort (hc);
diff --git a/src/include/taler_exchange_service.h 
b/src/include/taler_exchange_service.h
index bd2a5bca..6c3ad7a0 100644
--- a/src/include/taler_exchange_service.h
+++ b/src/include/taler_exchange_service.h
@@ -1047,6 +1047,144 @@ void
 TALER_EXCHANGE_deposit_cancel (struct TALER_EXCHANGE_DepositHandle *deposit);
 
 
+/**
+ * @brief A Batch Deposit Handle
+ */
+struct TALER_EXCHANGE_BatchDepositHandle;
+
+
+/**
+ * Structure with information about a batch deposit
+ * operation's result.
+ */
+struct TALER_EXCHANGE_BatchDepositResult
+{
+  /**
+   * HTTP response data
+   */
+  struct TALER_EXCHANGE_HttpResponse hr;
+
+  union
+  {
+
+    /**
+     * Information returned if the HTTP status is
+     * #MHD_HTTP_OK.
+     */
+    struct
+    {
+      /**
+       * Time when the exchange generated the batch deposit confirmation
+       */
+      struct GNUNET_TIME_Timestamp deposit_timestamp;
+
+      /**
+       * Array of signatures provided by the exchange
+       */
+      const struct TALER_ExchangeSignatureP *exchange_sigs;
+
+      /**
+       * exchange key used to sign @a exchange_sig.
+       */
+      const struct TALER_ExchangePublicKeyP *exchange_pub;
+
+      /**
+       * Base URL for looking up wire transfers, or
+       * NULL to use the default base URL.
+       */
+      const char *transaction_base_url;
+
+      /**
+       * Length of the @e exchange_sigs array.
+       */
+      unsigned int num_signatures;
+
+    } success;
+
+    /**
+     * Information returned if the HTTP status is
+     * #MHD_HTTP_CONFLICT.
+     */
+    struct
+    {
+      /* TODO: returning full details is not implemented */
+    } conflict;
+
+  } details;
+};
+
+
+/**
+ * Callbacks of this type are used to serve the result of submitting a
+ * deposit permission request to a exchange.
+ *
+ * @param cls closure
+ * @param dr deposit response details
+ */
+typedef void
+(*TALER_EXCHANGE_BatchDepositResultCallback) (
+  void *cls,
+  const struct TALER_EXCHANGE_BatchDepositResult *dr);
+
+
+/**
+ * Submit a batch of deposit permissions to the exchange and get the
+ * exchange's response.  This API is typically used by a merchant.  Note that
+ * while we return the response verbatim to the caller for further processing,
+ * we do already verify that the response is well-formed (i.e. that signatures
+ * included in the response are all valid).  If the exchange's reply is not
+ * well-formed, we return an HTTP status code of zero to @a cb.
+ *
+ * We also verify that the @a cdds.coin_sig are valid for this deposit
+ * request, and that the @a cdds.ub_sig are a valid signatures for @a
+ * coin_pub.  Also, the @a exchange must be ready to operate (i.e.  have
+ * finished processing the /keys reply).  If either check fails, we do
+ * NOT initiate the transaction with the exchange and instead return NULL.
+ *
+ * @param exchange the exchange handle; the exchange must be ready to operate
+ * @param dcd details about the contract the deposit is for
+ * @param num_cdds length of the @a cdds array
+ * @param cdds array with details about the coins to be deposited
+ * @param cb the callback to call when a reply for this request is available
+ * @param cb_cls closure for the above callback
+ * @param[out] ec if NULL is returned, set to the error code explaining why 
the operation failed
+ * @return a handle for this request; NULL if the inputs are invalid (i.e.
+ *         signatures fail to verify).  In this case, the callback is not 
called.
+ */
+struct TALER_EXCHANGE_BatchDepositHandle *
+TALER_EXCHANGE_batch_deposit (
+  struct TALER_EXCHANGE_Handle *exchange,
+  const struct TALER_EXCHANGE_DepositContractDetail *dcd,
+  unsigned int num_cdds,
+  const struct TALER_EXCHANGE_CoinDepositDetail *cdds,
+  TALER_EXCHANGE_BatchDepositResultCallback cb,
+  void *cb_cls,
+  enum TALER_ErrorCode *ec);
+
+
+/**
+ * Change the chance that our deposit confirmation will be given to the
+ * auditor to 100%.
+ *
+ * @param deposit the batch deposit permission request handle
+ */
+void
+TALER_EXCHANGE_batch_deposit_force_dc (struct
+                                       TALER_EXCHANGE_BatchDepositHandle *
+                                       deposit);
+
+
+/**
+ * Cancel a batch deposit permission request.  This function cannot be used
+ * on a request handle if a response is already served for it.
+ *
+ * @param deposit the deposit permission request handle
+ */
+void
+TALER_EXCHANGE_batch_deposit_cancel (struct
+                                     TALER_EXCHANGE_BatchDepositHandle 
*deposit);
+
+
 /* *********************  /coins/$COIN_PUB/refund *********************** */
 
 /**
diff --git a/src/include/taler_testing_lib.h b/src/include/taler_testing_lib.h
index f18816d6..6d3762b1 100644
--- a/src/include/taler_testing_lib.h
+++ b/src/include/taler_testing_lib.h
@@ -1614,6 +1614,32 @@ TALER_TESTING_cmd_deposit_replay (const char *label,
                                   unsigned int expected_response_code);
 
 
+/**
+ * Create a "batch deposit" command.
+ *
+ * @param label command label.
+ * @param target_account_payto target account for the "deposit"
+ *        request.
+ * @param contract_terms contract terms to be signed over by the
+ *        coin.
+ * @param refund_deadline refund deadline, zero means 'no refunds'.
+ * @param amount how much is going to be deposited.
+ * @param expected_response_code expected HTTP response code.
+ * @param ... NULL-terminated list with an even number of
+ *            strings that alternate referring to coins
+ *            (possibly with index using label#index notation)
+ *            and the amount of that coin to deposit
+ * @return the command.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_batch_deposit (const char *label,
+                                 const char *target_account_payto,
+                                 const char *contract_terms,
+                                 struct GNUNET_TIME_Relative refund_deadline,
+                                 unsigned int expected_response_code,
+                                 ...);
+
+
 /**
  * Create a "refresh melt" command.
  *
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index 844ca52f..76157c43 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -22,6 +22,7 @@ libtalerexchange_la_LDFLAGS = \
   -no-undefined
 libtalerexchange_la_SOURCES = \
   exchange_api_auditor_add_denomination.c \
+  exchange_api_batch_deposit.c \
   exchange_api_batch_withdraw.c \
   exchange_api_batch_withdraw2.c \
   exchange_api_curl_defaults.c exchange_api_curl_defaults.h \
diff --git a/src/lib/exchange_api_deposit.c 
b/src/lib/exchange_api_batch_deposit.c
similarity index 61%
copy from src/lib/exchange_api_deposit.c
copy to src/lib/exchange_api_batch_deposit.c
index 7e824617..be77f682 100644
--- a/src/lib/exchange_api_deposit.c
+++ b/src/lib/exchange_api_batch_deposit.c
@@ -1,6 +1,6 @@
 /*
    This file is part of TALER
-   Copyright (C) 2014-2021 Taler Systems SA
+   Copyright (C) 2014-2022 Taler Systems SA
 
    TALER is free software; you can redistribute it and/or modify it under the
    terms of the GNU General Public License as published by the Free Software
@@ -15,8 +15,8 @@
    <http://www.gnu.org/licenses/>
  */
 /**
- * @file lib/exchange_api_deposit.c
- * @brief Implementation of the /deposit request of the exchange's HTTP API
+ * @file lib/exchange_api_batch_deposit.c
+ * @brief Implementation of the /batch-deposit request of the exchange's HTTP 
API
  * @author Sree Harsha Totakura <sreeharsha@totakura.in>
  * @author Christian Grothoff
  */
@@ -47,7 +47,7 @@
 /**
  * @brief A Deposit Handle
  */
-struct TALER_EXCHANGE_DepositHandle
+struct TALER_EXCHANGE_BatchDepositHandle
 {
 
   /**
@@ -74,7 +74,7 @@ struct TALER_EXCHANGE_DepositHandle
   /**
    * Function to call with the result.
    */
-  TALER_EXCHANGE_DepositResultCallback cb;
+  TALER_EXCHANGE_BatchDepositResultCallback cb;
 
   /**
    * Closure for @a cb.
@@ -87,9 +87,9 @@ struct TALER_EXCHANGE_DepositHandle
   struct TALER_EXCHANGE_DepositContractDetail dcd;
 
   /**
-   * Details about the coin.
+   * Array with details about the coins.
    */
-  struct TALER_EXCHANGE_CoinDepositDetail cdd;
+  struct TALER_EXCHANGE_CoinDepositDetail *cdds;
 
   /**
    * Hash of the merchant's wire details.
@@ -108,9 +108,9 @@ struct TALER_EXCHANGE_DepositHandle
   struct GNUNET_TIME_Timestamp exchange_timestamp;
 
   /**
-   * Exchange signature, set for #auditor_cb.
+   * Exchange signatures, set for #auditor_cb.
    */
-  struct TALER_ExchangeSignatureP exchange_sig;
+  struct TALER_ExchangeSignatureP *exchange_sigs;
 
   /**
    * Exchange signing public key, set for #auditor_cb.
@@ -123,6 +123,11 @@ struct TALER_EXCHANGE_DepositHandle
    */
   unsigned int auditor_chance;
 
+  /**
+   * Length of the @e cdds array.
+   */
+  unsigned int num_cdds;
+
 };
 
 
@@ -140,12 +145,13 @@ auditor_cb (void *cls,
             struct TALER_AUDITOR_Handle *ah,
             const struct TALER_AuditorPublicKeyP *auditor_pub)
 {
-  struct TALER_EXCHANGE_DepositHandle *dh = cls;
+  struct TALER_EXCHANGE_BatchDepositHandle *dh = cls;
   const struct TALER_EXCHANGE_Keys *key_state;
   const struct TALER_EXCHANGE_SigningPublicKey *spk;
   struct TEAH_AuditorInteractionEntry *aie;
   struct TALER_Amount amount_without_fee;
   const struct TALER_EXCHANGE_DenomPublicKey *dki;
+  unsigned int coin;
 
   if (0 !=
       GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
@@ -155,12 +161,14 @@ auditor_cb (void *cls,
                 "Not providing deposit confirmation to auditor\n");
     return NULL;
   }
+  coin = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
+                                   dh->num_cdds);
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Will provide deposit confirmation to auditor `%s'\n",
               TALER_B2S (auditor_pub));
   key_state = TALER_EXCHANGE_get_keys (dh->exchange);
   dki = TALER_EXCHANGE_get_denomination_key_by_hash (key_state,
-                                                     &dh->cdd.h_denom_pub);
+                                                     
&dh->cdds[coin].h_denom_pub);
   GNUNET_assert (NULL != dki);
   spk = TALER_EXCHANGE_get_signing_key_info (key_state,
                                              &dh->exchange_pub);
@@ -171,7 +179,7 @@ auditor_cb (void *cls,
   }
   GNUNET_assert (0 <=
                  TALER_amount_subtract (&amount_without_fee,
-                                        &dh->cdd.amount,
+                                        &dh->cdds[coin].amount,
                                         &dki->fees.deposit));
   aie = GNUNET_new (struct TEAH_AuditorInteractionEntry);
   aie->dch = TALER_AUDITOR_deposit_confirmation (
@@ -183,10 +191,10 @@ auditor_cb (void *cls,
     dh->dcd.wire_deadline,
     dh->dcd.refund_deadline,
     &amount_without_fee,
-    &dh->cdd.coin_pub,
+    &dh->cdds[coin].coin_pub,
     &dh->dcd.merchant_pub,
     &dh->exchange_pub,
-    &dh->exchange_sig,
+    &dh->exchange_sigs[coin],
     &key_state->master_pub,
     spk->valid_from,
     spk->valid_until,
@@ -202,7 +210,7 @@ auditor_cb (void *cls,
  * Function called when we're done processing the
  * HTTP /deposit request.
  *
- * @param cls the `struct TALER_EXCHANGE_DepositHandle`
+ * @param cls the `struct TALER_EXCHANGE_BatchDepositHandle`
  * @param response_code HTTP response code, 0 on error
  * @param response parsed JSON result, NULL on error
  */
@@ -211,9 +219,9 @@ handle_deposit_finished (void *cls,
                          long response_code,
                          const void *response)
 {
-  struct TALER_EXCHANGE_DepositHandle *dh = cls;
+  struct TALER_EXCHANGE_BatchDepositHandle *dh = cls;
   const json_t *j = response;
-  struct TALER_EXCHANGE_DepositResult dr = {
+  struct TALER_EXCHANGE_BatchDepositResult dr = {
     .hr.reply = j,
     .hr.http_status = (unsigned int) response_code
   };
@@ -229,9 +237,12 @@ handle_deposit_finished (void *cls,
   case MHD_HTTP_OK:
     {
       const struct TALER_EXCHANGE_Keys *key_state;
+      json_t *sigs;
+      json_t *sig;
+      unsigned int idx;
       struct GNUNET_JSON_Specification spec[] = {
-        GNUNET_JSON_spec_fixed_auto ("exchange_sig",
-                                     &dh->exchange_sig),
+        GNUNET_JSON_spec_json ("exchange_sigs",
+                               &sigs),
         GNUNET_JSON_spec_fixed_auto ("exchange_pub",
                                      &dh->exchange_pub),
         GNUNET_JSON_spec_mark_optional (
@@ -242,8 +253,6 @@ handle_deposit_finished (void *cls,
                                     &dh->exchange_timestamp),
         GNUNET_JSON_spec_end ()
       };
-      struct TALER_Amount amount_without_fee;
-      const struct TALER_EXCHANGE_DenomPublicKey *dki;
 
       if (GNUNET_OK !=
           GNUNET_JSON_parse (j,
@@ -255,51 +264,83 @@ handle_deposit_finished (void *cls,
         dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
         break;
       }
-      key_state = TALER_EXCHANGE_get_keys (dh->exchange);
-      dki = TALER_EXCHANGE_get_denomination_key_by_hash (key_state,
-                                                         &dh->cdd.h_denom_pub);
-      GNUNET_assert (NULL != dki);
-      if (GNUNET_OK !=
-          TALER_EXCHANGE_test_signing_key (key_state,
-                                           &dh->exchange_pub))
+      if (json_array_size (sigs) != dh->num_cdds)
       {
         GNUNET_break_op (0);
         dr.hr.http_status = 0;
-        dr.hr.ec = TALER_EC_EXCHANGE_DEPOSIT_INVALID_SIGNATURE_BY_EXCHANGE;
+        dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
         break;
       }
-      GNUNET_assert (0 <=
-                     TALER_amount_subtract (&amount_without_fee,
-                                            &dh->cdd.amount,
-                                            &dki->fees.deposit));
-
+      dh->exchange_sigs = GNUNET_new_array (dh->num_cdds,
+                                            struct TALER_ExchangeSignatureP);
+      key_state = TALER_EXCHANGE_get_keys (dh->exchange);
       if (GNUNET_OK !=
-          TALER_exchange_online_deposit_confirmation_verify (
-            &dh->dcd.h_contract_terms,
-            &dh->h_wire,
-            &dh->h_extensions,
-            dh->exchange_timestamp,
-            dh->dcd.wire_deadline,
-            dh->dcd.refund_deadline,
-            &amount_without_fee,
-            &dh->cdd.coin_pub,
-            &dh->dcd.merchant_pub,
-            &dh->exchange_pub,
-            &dh->exchange_sig))
+          TALER_EXCHANGE_test_signing_key (key_state,
+                                           &dh->exchange_pub))
       {
         GNUNET_break_op (0);
         dr.hr.http_status = 0;
         dr.hr.ec = TALER_EC_EXCHANGE_DEPOSIT_INVALID_SIGNATURE_BY_EXCHANGE;
         break;
       }
-
+      json_array_foreach (sigs, idx, sig)
+      {
+        struct GNUNET_JSON_Specification ispec[] = {
+          GNUNET_JSON_spec_fixed_auto ("exchange_sig",
+                                       &dh->exchange_sigs[idx]),
+          GNUNET_JSON_spec_end ()
+        };
+        struct TALER_Amount amount_without_fee;
+        const struct TALER_EXCHANGE_DenomPublicKey *dki;
+
+        if (GNUNET_OK !=
+            GNUNET_JSON_parse (sig,
+                               ispec,
+                               NULL, NULL))
+        {
+          GNUNET_break_op (0);
+          dr.hr.http_status = 0;
+          dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
+          GNUNET_JSON_parse_free (spec);
+          break;
+        }
+        dki = TALER_EXCHANGE_get_denomination_key_by_hash (key_state,
+                                                           &dh->cdds[idx].
+                                                           h_denom_pub);
+        GNUNET_assert (NULL != dki);
+        GNUNET_assert (0 <=
+                       TALER_amount_subtract (&amount_without_fee,
+                                              &dh->cdds[idx].amount,
+                                              &dki->fees.deposit));
+
+        if (GNUNET_OK !=
+            TALER_exchange_online_deposit_confirmation_verify (
+              &dh->dcd.h_contract_terms,
+              &dh->h_wire,
+              &dh->h_extensions,
+              dh->exchange_timestamp,
+              dh->dcd.wire_deadline,
+              dh->dcd.refund_deadline,
+              &amount_without_fee,
+              &dh->cdds[idx].coin_pub,
+              &dh->dcd.merchant_pub,
+              &dh->exchange_pub,
+              &dh->exchange_sigs[idx]))
+        {
+          GNUNET_break_op (0);
+          dr.hr.http_status = 0;
+          dr.hr.ec = TALER_EC_EXCHANGE_DEPOSIT_INVALID_SIGNATURE_BY_EXCHANGE;
+          break;
+        }
+      }
       TEAH_get_auditors_for_dc (dh->exchange,
                                 &auditor_cb,
                                 dh);
     }
-    dr.details.success.exchange_sig = &dh->exchange_sig;
+    dr.details.success.exchange_sigs = dh->exchange_sigs;
     dr.details.success.exchange_pub = &dh->exchange_pub;
     dr.details.success.deposit_timestamp = dh->exchange_timestamp;
+    dr.details.success.num_signatures = dh->num_cdds;
     break;
   case MHD_HTTP_BAD_REQUEST:
     /* This should never happen, either us or the exchange is buggy
@@ -323,28 +364,62 @@ handle_deposit_finished (void *cls,
   case MHD_HTTP_CONFLICT:
     {
       const struct TALER_EXCHANGE_Keys *key_state;
+      struct TALER_CoinSpendPublicKeyP coin_pub;
+      struct GNUNET_JSON_Specification spec[] = {
+        GNUNET_JSON_spec_fixed_auto ("coin_pub",
+                                     &coin_pub),
+        GNUNET_JSON_spec_end ()
+      };
       const struct TALER_EXCHANGE_DenomPublicKey *dki;
+      bool found = false;
 
-      key_state = TALER_EXCHANGE_get_keys (dh->exchange);
-      dki = TALER_EXCHANGE_get_denomination_key_by_hash (key_state,
-                                                         &dh->cdd.h_denom_pub);
-      GNUNET_assert (NULL != dki);
-      dr.hr.ec = TALER_JSON_get_error_code (j);
-      dr.hr.hint = TALER_JSON_get_error_hint (j);
       if (GNUNET_OK !=
-          TALER_EXCHANGE_check_coin_conflict_ (
-            keys,
-            j,
-            dki,
-            &dh->cdd.coin_pub,
-            &dh->cdd.coin_sig,
-            &dh->cdd.amount))
+          GNUNET_JSON_parse (j,
+                             spec,
+                             NULL, NULL))
       {
         GNUNET_break_op (0);
         dr.hr.http_status = 0;
         dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
         break;
       }
+      for (unsigned int i = 0; i<dh->num_cdds; i++)
+      {
+        if (0 !=
+            GNUNET_memcmp (&coin_pub,
+                           &dh->cdds[i].coin_pub))
+          continue;
+        key_state = TALER_EXCHANGE_get_keys (dh->exchange);
+        dki = TALER_EXCHANGE_get_denomination_key_by_hash (key_state,
+                                                           &dh->cdds[i].
+                                                           h_denom_pub);
+        GNUNET_assert (NULL != dki);
+        if (GNUNET_OK !=
+            TALER_EXCHANGE_check_coin_conflict_ (
+              keys,
+              j,
+              dki,
+              &dh->cdds[i].coin_pub,
+              &dh->cdds[i].coin_sig,
+              &dh->cdds[i].amount))
+        {
+          GNUNET_break_op (0);
+          dr.hr.http_status = 0;
+          dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
+          break;
+        }
+        found = true;
+        break;
+      }
+      if (! found)
+      {
+        GNUNET_break_op (0);
+        dr.hr.http_status = 0;
+        dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
+        break;
+      }
+      dr.hr.ec = TALER_JSON_get_error_code (j);
+      dr.hr.hint = TALER_JSON_get_error_hint (j);
     }
     break;
   case MHD_HTTP_GONE:
@@ -374,98 +449,27 @@ handle_deposit_finished (void *cls,
   }
   dh->cb (dh->cb_cls,
           &dr);
-  TALER_EXCHANGE_deposit_cancel (dh);
-}
-
-
-/**
- * Verify signature information about the deposit.
- *
- * @param dcd contract details
- * @param ech hashed contract (passed to avoid recomputation)
- * @param h_wire hashed wire details (passed to avoid recomputation)
- * @param cdd coin-specific details
- * @param dki denomination of the coin
- * @return #GNUNET_OK if signatures are OK, #GNUNET_SYSERR if not
- */
-static enum GNUNET_GenericReturnValue
-verify_signatures (const struct TALER_EXCHANGE_DepositContractDetail *dcd,
-                   const struct TALER_ExtensionContractHashP *ech,
-                   const struct TALER_MerchantWireHashP *h_wire,
-                   const struct TALER_EXCHANGE_CoinDepositDetail *cdd,
-                   const struct TALER_EXCHANGE_DenomPublicKey *dki)
-{
-  if (GNUNET_OK !=
-      TALER_wallet_deposit_verify (&cdd->amount,
-                                   &dki->fees.deposit,
-                                   h_wire,
-                                   &dcd->h_contract_terms,
-                                   &cdd->h_age_commitment,
-                                   ech,
-                                   &cdd->h_denom_pub,
-                                   dcd->timestamp,
-                                   &dcd->merchant_pub,
-                                   dcd->refund_deadline,
-                                   &cdd->coin_pub,
-                                   &cdd->coin_sig))
-  {
-    GNUNET_break_op (0);
-    TALER_LOG_WARNING ("Invalid coin signature on /deposit request!\n");
-    TALER_LOG_DEBUG ("... amount_with_fee was %s\n",
-                     TALER_amount2s (&cdd->amount));
-    TALER_LOG_DEBUG ("... deposit_fee was %s\n",
-                     TALER_amount2s (&dki->fees.deposit));
-    return GNUNET_SYSERR;
-  }
-
-  /* check coin signature */
-  {
-    struct TALER_CoinPublicInfo coin_info = {
-      .coin_pub = cdd->coin_pub,
-      .denom_pub_hash = cdd->h_denom_pub,
-      .denom_sig = cdd->denom_sig,
-      .h_age_commitment = cdd->h_age_commitment,
-    };
-
-    if (GNUNET_YES !=
-        TALER_test_coin_valid (&coin_info,
-                               &dki->key))
-    {
-      GNUNET_break_op (0);
-      TALER_LOG_WARNING ("Invalid coin passed for /deposit\n");
-      return GNUNET_SYSERR;
-    }
-  }
-
-  /* Check coin does make a contribution */
-  if (0 < TALER_amount_cmp (&dki->fees.deposit,
-                            &cdd->amount))
-  {
-    GNUNET_break_op (0);
-    TALER_LOG_WARNING ("Deposit amount smaller than fee\n");
-    return GNUNET_SYSERR;
-  }
-  return GNUNET_OK;
+  TALER_EXCHANGE_batch_deposit_cancel (dh);
 }
 
 
-struct TALER_EXCHANGE_DepositHandle *
-TALER_EXCHANGE_deposit (
+struct TALER_EXCHANGE_BatchDepositHandle *
+TALER_EXCHANGE_batch_deposit (
   struct TALER_EXCHANGE_Handle *exchange,
   const struct TALER_EXCHANGE_DepositContractDetail *dcd,
-  const struct TALER_EXCHANGE_CoinDepositDetail *cdd,
-  TALER_EXCHANGE_DepositResultCallback cb,
+  unsigned int num_cdds,
+  const struct TALER_EXCHANGE_CoinDepositDetail *cdds,
+  TALER_EXCHANGE_BatchDepositResultCallback cb,
   void *cb_cls,
   enum TALER_ErrorCode *ec)
 {
   const struct TALER_EXCHANGE_Keys *key_state;
-  struct TALER_EXCHANGE_DepositHandle *dh;
+  struct TALER_EXCHANGE_BatchDepositHandle *dh;
   struct GNUNET_CURL_Context *ctx;
   json_t *deposit_obj;
+  json_t *deposits;
   CURL *eh;
-  const struct TALER_EXCHANGE_DenomPublicKey *dki;
   struct TALER_Amount amount_without_fee;
-  char arg_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2 + 32];
 
   GNUNET_assert (GNUNET_YES ==
                  TEAH_handle_is_ready (exchange));
@@ -477,47 +481,16 @@ TALER_EXCHANGE_deposit (
     *ec = TALER_EC_EXCHANGE_DEPOSIT_REFUND_DEADLINE_AFTER_WIRE_DEADLINE;
     return NULL;
   }
-  {
-    char pub_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2];
-    char *end;
-
-    end = GNUNET_STRINGS_data_to_string (
-      &cdd->coin_pub,
-      sizeof (struct TALER_CoinSpendPublicKeyP),
-      pub_str,
-      sizeof (pub_str));
-    *end = '\0';
-    GNUNET_snprintf (arg_str,
-                     sizeof (arg_str),
-                     "/coins/%s/deposit",
-                     pub_str);
-  }
-
   key_state = TALER_EXCHANGE_get_keys (exchange);
-  dki = TALER_EXCHANGE_get_denomination_key_by_hash (key_state,
-                                                     &cdd->h_denom_pub);
-  if (NULL == dki)
-  {
-    *ec = TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN;
-    GNUNET_break_op (0);
-    return NULL;
-  }
-
-  if (0 >
-      TALER_amount_subtract (&amount_without_fee,
-                             &cdd->amount,
-                             &dki->fees.deposit))
-  {
-    *ec = TALER_EC_EXCHANGE_DEPOSIT_FEE_ABOVE_AMOUNT;
-    GNUNET_break_op (0);
-    return NULL;
-  }
-  dh = GNUNET_new (struct TALER_EXCHANGE_DepositHandle);
+  dh = GNUNET_new (struct TALER_EXCHANGE_BatchDepositHandle);
   dh->auditor_chance = AUDITOR_CHANCE;
   dh->exchange = exchange;
   dh->cb = cb;
   dh->cb_cls = cb_cls;
-  dh->cdd = *cdd;
+  dh->cdds = GNUNET_memdup (cdds,
+                            num_cdds
+                            * sizeof (*cdds));
+  dh->num_cdds = num_cdds;
   dh->dcd = *dcd;
   if (NULL != dcd->extension_details)
     TALER_deposit_extension_hash (dcd->extension_details,
@@ -525,45 +498,85 @@ TALER_EXCHANGE_deposit (
   TALER_merchant_wire_signature_hash (dcd->merchant_payto_uri,
                                       &dcd->wire_salt,
                                       &dh->h_wire);
-  if (GNUNET_OK !=
-      verify_signatures (dcd,
-                         &dh->h_extensions,
-                         &dh->h_wire,
-                         cdd,
-                         dki))
+  deposits = json_array ();
+  GNUNET_assert (NULL != deposits);
+  for (unsigned int i = 0; i<num_cdds; i++)
   {
-    *ec = TALER_EC_EXCHANGE_DEPOSIT_COIN_SIGNATURE_INVALID;
-    GNUNET_break_op (0);
-    GNUNET_free (dh);
-    return NULL;
+    const struct TALER_EXCHANGE_CoinDepositDetail *cdd = &cdds[i];
+    const struct TALER_EXCHANGE_DenomPublicKey *dki;
+
+    dki = TALER_EXCHANGE_get_denomination_key_by_hash (key_state,
+                                                       &cdd->h_denom_pub);
+    if (NULL == dki)
+    {
+      *ec = TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN;
+      GNUNET_break_op (0);
+      return NULL;
+    }
+    if (0 >
+        TALER_amount_subtract (&amount_without_fee,
+                               &cdd->amount,
+                               &dki->fees.deposit))
+    {
+      *ec = TALER_EC_EXCHANGE_DEPOSIT_FEE_ABOVE_AMOUNT;
+      GNUNET_break_op (0);
+      GNUNET_free (dh->cdds);
+      GNUNET_free (dh);
+      return NULL;
+    }
+
+    if (GNUNET_OK !=
+        TALER_EXCHANGE_verify_deposit_signature_ (dcd,
+                                                  &dh->h_extensions,
+                                                  &dh->h_wire,
+                                                  cdd,
+                                                  dki))
+    {
+      *ec = TALER_EC_EXCHANGE_DEPOSIT_COIN_SIGNATURE_INVALID;
+      GNUNET_break_op (0);
+      GNUNET_free (dh->cdds);
+      GNUNET_free (dh);
+      return NULL;
+    }
+    GNUNET_assert (
+      0 ==
+      json_array_append_new (
+        deposits,
+        GNUNET_JSON_PACK (
+          TALER_JSON_pack_amount ("contribution",
+                                  &cdd->amount),
+          GNUNET_JSON_pack_allow_null (
+            GNUNET_JSON_pack_data_auto ("h_age_commitment",
+                                        &cdd->h_age_commitment)),
+          GNUNET_JSON_pack_data_auto ("denom_pub_hash",
+                                      &cdd->h_denom_pub),
+          TALER_JSON_pack_denom_sig ("ub_sig",
+                                     &cdd->denom_sig),
+          GNUNET_JSON_pack_data_auto ("coin_sig",
+                                      &cdd->coin_sig)
+          )));
   }
   dh->url = TEAH_path_to_url (exchange,
-                              arg_str);
+                              "/batch-deposit");
   if (NULL == dh->url)
   {
     GNUNET_break (0);
     *ec = TALER_EC_GENERIC_ALLOCATION_FAILURE;
     GNUNET_free (dh->url);
+    GNUNET_free (dh->cdds);
     GNUNET_free (dh);
     return NULL;
   }
 
   deposit_obj = GNUNET_JSON_PACK (
-    TALER_JSON_pack_amount ("contribution",
-                            &cdd->amount),
+    GNUNET_JSON_pack_array_steal ("coins",
+                                  deposits),
     GNUNET_JSON_pack_string ("merchant_payto_uri",
                              dcd->merchant_payto_uri),
     GNUNET_JSON_pack_data_auto ("wire_salt",
                                 &dcd->wire_salt),
     GNUNET_JSON_pack_data_auto ("h_contract_terms",
                                 &dcd->h_contract_terms),
-    GNUNET_JSON_pack_allow_null (
-      GNUNET_JSON_pack_data_auto ("h_age_commitment",
-                                  &cdd->h_age_commitment)),
-    GNUNET_JSON_pack_data_auto ("denom_pub_hash",
-                                &cdd->h_denom_pub),
-    TALER_JSON_pack_denom_sig ("ub_sig",
-                               &cdd->denom_sig),
     GNUNET_JSON_pack_timestamp ("timestamp",
                                 dcd->timestamp),
     GNUNET_JSON_pack_data_auto ("merchant_pub",
@@ -572,9 +585,7 @@ TALER_EXCHANGE_deposit (
       GNUNET_JSON_pack_timestamp ("refund_deadline",
                                   dcd->refund_deadline)),
     GNUNET_JSON_pack_timestamp ("wire_transfer_deadline",
-                                dcd->wire_deadline),
-    GNUNET_JSON_pack_data_auto ("coin_sig",
-                                &cdd->coin_sig));
+                                dcd->wire_deadline));
   GNUNET_assert (NULL != deposit_obj);
   eh = TALER_EXCHANGE_curl_easy_get_ (dh->url);
   if ( (NULL == eh) ||
@@ -588,6 +599,7 @@ TALER_EXCHANGE_deposit (
     if (NULL != eh)
       curl_easy_cleanup (eh);
     json_decref (deposit_obj);
+    GNUNET_free (dh->cdds);
     GNUNET_free (dh->url);
     GNUNET_free (dh);
     return NULL;
@@ -607,14 +619,17 @@ TALER_EXCHANGE_deposit (
 
 
 void
-TALER_EXCHANGE_deposit_force_dc (struct TALER_EXCHANGE_DepositHandle *deposit)
+TALER_EXCHANGE_batch_deposit_force_dc (struct
+                                       TALER_EXCHANGE_BatchDepositHandle *
+                                       deposit)
 {
   deposit->auditor_chance = 1;
 }
 
 
 void
-TALER_EXCHANGE_deposit_cancel (struct TALER_EXCHANGE_DepositHandle *deposit)
+TALER_EXCHANGE_batch_deposit_cancel (struct
+                                     TALER_EXCHANGE_BatchDepositHandle 
*deposit)
 {
   if (NULL != deposit->job)
   {
@@ -622,9 +637,11 @@ TALER_EXCHANGE_deposit_cancel (struct 
TALER_EXCHANGE_DepositHandle *deposit)
     deposit->job = NULL;
   }
   GNUNET_free (deposit->url);
+  GNUNET_free (deposit->cdds);
+  GNUNET_free (deposit->exchange_sigs);
   TALER_curl_easy_post_finished (&deposit->ctx);
   GNUNET_free (deposit);
 }
 
 
-/* end of exchange_api_deposit.c */
+/* end of exchange_api_batch_deposit.c */
diff --git a/src/lib/exchange_api_common.c b/src/lib/exchange_api_common.c
index 26ddb3c0..739b215f 100644
--- a/src/lib/exchange_api_common.c
+++ b/src/lib/exchange_api_common.c
@@ -1946,4 +1946,66 @@ TALER_EXCHANGE_get_min_denomination_ (
 }
 
 
+enum GNUNET_GenericReturnValue
+TALER_EXCHANGE_verify_deposit_signature_ (
+  const struct TALER_EXCHANGE_DepositContractDetail *dcd,
+  const struct TALER_ExtensionContractHashP *ech,
+  const struct TALER_MerchantWireHashP *h_wire,
+  const struct TALER_EXCHANGE_CoinDepositDetail *cdd,
+  const struct TALER_EXCHANGE_DenomPublicKey *dki)
+{
+  if (GNUNET_OK !=
+      TALER_wallet_deposit_verify (&cdd->amount,
+                                   &dki->fees.deposit,
+                                   h_wire,
+                                   &dcd->h_contract_terms,
+                                   &cdd->h_age_commitment,
+                                   ech,
+                                   &cdd->h_denom_pub,
+                                   dcd->timestamp,
+                                   &dcd->merchant_pub,
+                                   dcd->refund_deadline,
+                                   &cdd->coin_pub,
+                                   &cdd->coin_sig))
+  {
+    GNUNET_break_op (0);
+    TALER_LOG_WARNING ("Invalid coin signature on /deposit request!\n");
+    TALER_LOG_DEBUG ("... amount_with_fee was %s\n",
+                     TALER_amount2s (&cdd->amount));
+    TALER_LOG_DEBUG ("... deposit_fee was %s\n",
+                     TALER_amount2s (&dki->fees.deposit));
+    return GNUNET_SYSERR;
+  }
+
+  /* check coin signature */
+  {
+    struct TALER_CoinPublicInfo coin_info = {
+      .coin_pub = cdd->coin_pub,
+      .denom_pub_hash = cdd->h_denom_pub,
+      .denom_sig = cdd->denom_sig,
+      .h_age_commitment = cdd->h_age_commitment,
+    };
+
+    if (GNUNET_YES !=
+        TALER_test_coin_valid (&coin_info,
+                               &dki->key))
+    {
+      GNUNET_break_op (0);
+      TALER_LOG_WARNING ("Invalid coin passed for /deposit\n");
+      return GNUNET_SYSERR;
+    }
+  }
+
+  /* Check coin does make a contribution */
+  if (0 < TALER_amount_cmp (&dki->fees.deposit,
+                            &cdd->amount))
+  {
+    GNUNET_break_op (0);
+    TALER_LOG_WARNING ("Deposit amount smaller than fee\n");
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
+}
+
+
 /* end of exchange_api_common.c */
diff --git a/src/lib/exchange_api_common.h b/src/lib/exchange_api_common.h
index f4737ca9..a75ed3ed 100644
--- a/src/lib/exchange_api_common.h
+++ b/src/lib/exchange_api_common.h
@@ -198,4 +198,24 @@ TALER_EXCHANGE_get_min_denomination_ (
   const struct TALER_EXCHANGE_Keys *keys,
   struct TALER_Amount *min);
 
+
+/**
+ * Verify signature information about the deposit.
+ *
+ * @param dcd contract details
+ * @param ech hashed contract (passed to avoid recomputation)
+ * @param h_wire hashed wire details (passed to avoid recomputation)
+ * @param cdd coin-specific details
+ * @param dki denomination of the coin
+ * @return #GNUNET_OK if signatures are OK, #GNUNET_SYSERR if not
+ */
+enum GNUNET_GenericReturnValue
+TALER_EXCHANGE_verify_deposit_signature_ (
+  const struct TALER_EXCHANGE_DepositContractDetail *dcd,
+  const struct TALER_ExtensionContractHashP *ech,
+  const struct TALER_MerchantWireHashP *h_wire,
+  const struct TALER_EXCHANGE_CoinDepositDetail *cdd,
+  const struct TALER_EXCHANGE_DenomPublicKey *dki);
+
+
 #endif
diff --git a/src/lib/exchange_api_deposit.c b/src/lib/exchange_api_deposit.c
index 7e824617..32964341 100644
--- a/src/lib/exchange_api_deposit.c
+++ b/src/lib/exchange_api_deposit.c
@@ -378,77 +378,6 @@ handle_deposit_finished (void *cls,
 }
 
 
-/**
- * Verify signature information about the deposit.
- *
- * @param dcd contract details
- * @param ech hashed contract (passed to avoid recomputation)
- * @param h_wire hashed wire details (passed to avoid recomputation)
- * @param cdd coin-specific details
- * @param dki denomination of the coin
- * @return #GNUNET_OK if signatures are OK, #GNUNET_SYSERR if not
- */
-static enum GNUNET_GenericReturnValue
-verify_signatures (const struct TALER_EXCHANGE_DepositContractDetail *dcd,
-                   const struct TALER_ExtensionContractHashP *ech,
-                   const struct TALER_MerchantWireHashP *h_wire,
-                   const struct TALER_EXCHANGE_CoinDepositDetail *cdd,
-                   const struct TALER_EXCHANGE_DenomPublicKey *dki)
-{
-  if (GNUNET_OK !=
-      TALER_wallet_deposit_verify (&cdd->amount,
-                                   &dki->fees.deposit,
-                                   h_wire,
-                                   &dcd->h_contract_terms,
-                                   &cdd->h_age_commitment,
-                                   ech,
-                                   &cdd->h_denom_pub,
-                                   dcd->timestamp,
-                                   &dcd->merchant_pub,
-                                   dcd->refund_deadline,
-                                   &cdd->coin_pub,
-                                   &cdd->coin_sig))
-  {
-    GNUNET_break_op (0);
-    TALER_LOG_WARNING ("Invalid coin signature on /deposit request!\n");
-    TALER_LOG_DEBUG ("... amount_with_fee was %s\n",
-                     TALER_amount2s (&cdd->amount));
-    TALER_LOG_DEBUG ("... deposit_fee was %s\n",
-                     TALER_amount2s (&dki->fees.deposit));
-    return GNUNET_SYSERR;
-  }
-
-  /* check coin signature */
-  {
-    struct TALER_CoinPublicInfo coin_info = {
-      .coin_pub = cdd->coin_pub,
-      .denom_pub_hash = cdd->h_denom_pub,
-      .denom_sig = cdd->denom_sig,
-      .h_age_commitment = cdd->h_age_commitment,
-    };
-
-    if (GNUNET_YES !=
-        TALER_test_coin_valid (&coin_info,
-                               &dki->key))
-    {
-      GNUNET_break_op (0);
-      TALER_LOG_WARNING ("Invalid coin passed for /deposit\n");
-      return GNUNET_SYSERR;
-    }
-  }
-
-  /* Check coin does make a contribution */
-  if (0 < TALER_amount_cmp (&dki->fees.deposit,
-                            &cdd->amount))
-  {
-    GNUNET_break_op (0);
-    TALER_LOG_WARNING ("Deposit amount smaller than fee\n");
-    return GNUNET_SYSERR;
-  }
-  return GNUNET_OK;
-}
-
-
 struct TALER_EXCHANGE_DepositHandle *
 TALER_EXCHANGE_deposit (
   struct TALER_EXCHANGE_Handle *exchange,
@@ -526,11 +455,11 @@ TALER_EXCHANGE_deposit (
                                       &dcd->wire_salt,
                                       &dh->h_wire);
   if (GNUNET_OK !=
-      verify_signatures (dcd,
-                         &dh->h_extensions,
-                         &dh->h_wire,
-                         cdd,
-                         dki))
+      TALER_EXCHANGE_verify_deposit_signature_ (dcd,
+                                                &dh->h_extensions,
+                                                &dh->h_wire,
+                                                cdd,
+                                                dki))
   {
     *ec = TALER_EC_EXCHANGE_DEPOSIT_COIN_SIGNATURE_INVALID;
     GNUNET_break_op (0);
diff --git a/src/lib/exchange_api_handle.c b/src/lib/exchange_api_handle.c
index 3cdc8ad2..488a419b 100644
--- a/src/lib/exchange_api_handle.c
+++ b/src/lib/exchange_api_handle.c
@@ -992,7 +992,7 @@ decode_keys_json (const json_t *resp_obj,
                                                  check_sig,
                                                  denom_key_obj,
                                                  &key_data->master_pub,
-                                                 check_sig ? &hash_xor: NULL));
+                                                 check_sig ? &hash_xor : 
NULL));
 
           // Build the running xor of the SHA512-hash of the public keys
           {
diff --git a/src/lib/exchange_api_purse_create_with_deposit.c 
b/src/lib/exchange_api_purse_create_with_deposit.c
index 3a5b7df5..ce0221aa 100644
--- a/src/lib/exchange_api_purse_create_with_deposit.c
+++ b/src/lib/exchange_api_purse_create_with_deposit.c
@@ -680,8 +680,8 @@ TALER_EXCHANGE_purse_create_with_deposit (
     GNUNET_JSON_pack_allow_null (
       TALER_JSON_pack_econtract ("econtract",
                                  upload_contract
-                                  ? &pch->econtract
-                                  : NULL)),
+                                 ? &pch->econtract
+                                 : NULL)),
     GNUNET_JSON_pack_data_auto ("purse_sig",
                                 &pch->purse_sig),
     GNUNET_JSON_pack_data_auto ("merge_pub",
diff --git a/src/lib/exchange_api_purse_create_with_merge.c 
b/src/lib/exchange_api_purse_create_with_merge.c
index 2b4f1cd2..f3c72d4f 100644
--- a/src/lib/exchange_api_purse_create_with_merge.c
+++ b/src/lib/exchange_api_purse_create_with_merge.c
@@ -478,8 +478,8 @@ TALER_EXCHANGE_purse_create_with_merge (
     GNUNET_JSON_pack_allow_null (
       TALER_JSON_pack_econtract ("econtract",
                                  upload_contract
-                                  ? &pcm->econtract
-                                  : NULL)),
+                                 ? &pcm->econtract
+                                 : NULL)),
     GNUNET_JSON_pack_allow_null (
       pay_for_purse
       ? TALER_JSON_pack_amount ("purse_fee",

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]