gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] 23/37: implement withdraw (nonce reuse check missing)


From: gnunet
Subject: [taler-exchange] 23/37: implement withdraw (nonce reuse check missing)
Date: Fri, 04 Feb 2022 16:53:53 +0100

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

gian-demarmels pushed a commit to branch master
in repository exchange.

commit 9074e66ebc8b73ecc98500f32af52088fd7f0722
Author: Lucien Heuzeveldt <lucienclaude.heuzeveldt@students.bfh.ch>
AuthorDate: Sat Jan 8 20:41:01 2022 +0100

    implement withdraw (nonce reuse check missing)
---
 src/exchange/taler-exchange-httpd_csr.c      |   4 -
 src/exchange/taler-exchange-httpd_keys.c     |  14 ++-
 src/exchange/taler-exchange-httpd_withdraw.c | 164 ++++++++++++++++++++++++---
 src/include/taler_testing_lib.h              |  24 ++++
 src/json/json_helper.c                       |  24 ++++
 src/json/json_pack.c                         |  21 ++--
 src/lib/exchange_api_withdraw.c              |  88 +++++++++-----
 src/lib/exchange_api_withdraw2.c             |  74 +++++++++---
 src/pq/pq_query_helper.c                     |  20 +++-
 src/pq/pq_result_helper.c                    |  11 +-
 src/testing/test_exchange_api.c              |  58 +++++-----
 src/testing/testing_api_cmd_withdraw.c       |  32 ++++--
 12 files changed, 425 insertions(+), 109 deletions(-)

diff --git a/src/exchange/taler-exchange-httpd_csr.c 
b/src/exchange/taler-exchange-httpd_csr.c
index 0e330fe3..415dc7ac 100644
--- a/src/exchange/taler-exchange-httpd_csr.c
+++ b/src/exchange/taler-exchange-httpd_csr.c
@@ -37,10 +37,6 @@ TEH_handler_csr (struct TEH_RequestContext *rc,
                  const json_t *root,
                  const char *const args[])
 {
-  // TODO: should we have something similar to struct WithdrawContext?
-  // as far as I can tell this isn't necessary because we don't have
-  // other functions that the context should be passed to
-  // struct CsRContext csrc;
   struct TALER_WithdrawNonce nonce;
   struct TALER_DenominationHash denom_pub_hash;
   struct TALER_DenominationCsPublicR r_pub;
diff --git a/src/exchange/taler-exchange-httpd_keys.c 
b/src/exchange/taler-exchange-httpd_keys.c
index dd5928fb..66c0f69e 100644
--- a/src/exchange/taler-exchange-httpd_keys.c
+++ b/src/exchange/taler-exchange-httpd_keys.c
@@ -2442,7 +2442,19 @@ TEH_keys_denomination_sign (const struct 
TALER_DenominationHash *h_denom_pub,
                                          msg,
                                          msg_size,
                                          ec);
-  // TODO: case TALER_DENOMINATION_CS:
+  case TALER_DENOMINATION_CS:
+    if (sizeof (struct TALER_BlindedCsPlanchet) != msg_size)
+    {
+      *ec = TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE;
+      return none;
+    }
+    struct TALER_BlindedCsPlanchet *blinded_cs_planchet = ((struct
+                                                            
TALER_BlindedCsPlanchet
+                                                            *) msg);
+    return TALER_CRYPTO_helper_cs_sign (ksh->helpers->csdh,
+                                        &hd->h_details.h_cs,
+                                        blinded_cs_planchet,
+                                        ec);
   default:
     *ec = TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE;
     return none;
diff --git a/src/exchange/taler-exchange-httpd_withdraw.c 
b/src/exchange/taler-exchange-httpd_withdraw.c
index 53ba270b..ed54fe27 100644
--- a/src/exchange/taler-exchange-httpd_withdraw.c
+++ b/src/exchange/taler-exchange-httpd_withdraw.c
@@ -98,15 +98,13 @@ struct WithdrawContext
   /**
    * Blinded planchet.
    */
-  void *blinded_msg;
+  //FIXME:
 
   /**
    * Number of bytes in @e blinded_msg.
    */
   size_t blinded_msg_len;
-
-  /**
-   * Set to the resulting signed coin data to be returned to the client.
+  struct TALER_BlindedPlanchet blinded_planchet;
    */
   struct TALER_EXCHANGEDB_CollectableBlindcoin collectable;
 
@@ -324,15 +322,48 @@ TEH_handler_withdraw (struct TEH_RequestContext *rc,
 {
   struct WithdrawContext wc;
   struct GNUNET_JSON_Specification spec[] = {
+    //FIXME:
     GNUNET_JSON_spec_varsize ("coin_ev",
                               &wc.blinded_msg,
                               &wc.blinded_msg_len),
+    // field "coin_ev" will be parsed later due to different parsing depending
+    // on denomination cipher, see coin_ev_..._spec
     GNUNET_JSON_spec_fixed_auto ("reserve_sig",
                                  &wc.collectable.reserve_sig),
     GNUNET_JSON_spec_fixed_auto ("denom_pub_hash",
                                  &wc.collectable.denom_pub_hash),
     GNUNET_JSON_spec_end ()
   };
+  // holds pointer to coin_ev_rsa/cs_spec for freeing
+  struct GNUNET_JSON_Specification *coin_ev_spec = NULL;
+  struct GNUNET_JSON_Specification coin_ev_rsa_spec[] = {
+    GNUNET_JSON_spec_varsize (
+      "coin_ev",
+      (void **) &wc.blinded_planchet.details.rsa_blinded_planchet.blinded_msg,
+      &wc.blinded_planchet.details.rsa_blinded_planchet.blinded_msg_size),
+    GNUNET_JSON_spec_end ()
+  };
+  json_t *coin_ev_cs_json;
+  struct GNUNET_JSON_Specification coin_ev_cs_json_spec[] = {
+    GNUNET_JSON_spec_json ("coin_ev",
+                           &coin_ev_cs_json),
+    GNUNET_JSON_spec_end ()
+  };
+  struct GNUNET_JSON_Specification coin_ev_cs_spec[] = {
+    GNUNET_JSON_spec_fixed (
+      "nonce",
+      &wc.blinded_planchet.details.cs_blinded_planchet.nonce,
+      sizeof (wc.blinded_planchet.details.cs_blinded_planchet.nonce)),
+    GNUNET_JSON_spec_fixed (
+      "c0",
+      &wc.blinded_planchet.details.cs_blinded_planchet.c[0],
+      sizeof (wc.blinded_planchet.details.cs_blinded_planchet.c[0])),
+    GNUNET_JSON_spec_fixed (
+      "c1",
+      &wc.blinded_planchet.details.cs_blinded_planchet.c[1],
+      sizeof (wc.blinded_planchet.details.cs_blinded_planchet.c[1])),
+    GNUNET_JSON_spec_end ()
+  };
   enum TALER_ErrorCode ec;
   struct TEH_DenominationKey *dk;
 
@@ -445,7 +476,7 @@ TEH_handler_withdraw (struct TEH_RequestContext *rc,
       return mret;
     }
   }
-
+//FIXME:
   if (0 >
       TALER_amount_add (&wc.collectable.amount_with_fee,
                         &dk->meta.value,
@@ -456,6 +487,61 @@ TEH_handler_withdraw (struct TEH_RequestContext *rc,
                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
                                        
TALER_EC_EXCHANGE_WITHDRAW_AMOUNT_FEE_OVERFLOW,
                                        NULL);
+  // parse coin_ev field, must be done after dk lookup to know denom cipher
+  {
+    enum GNUNET_GenericReturnValue res;
+    wc.blinded_planchet.cipher = dk->denom_pub.cipher;
+    switch (wc.blinded_planchet.cipher)
+    {
+    case TALER_DENOMINATION_RSA:
+      res = TALER_MHD_parse_json_data (rc->connection,
+                                       root,
+                                       coin_ev_rsa_spec);
+      if (GNUNET_OK != res)
+        return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
+      coin_ev_spec = coin_ev_rsa_spec;
+      break;
+    case TALER_DENOMINATION_CS:
+      // coin_ev for CS is nested
+      res = TALER_MHD_parse_json_data (rc->connection,
+                                       root,
+                                       coin_ev_cs_json_spec);
+      if (GNUNET_OK != res)
+        return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
+      res = TALER_MHD_parse_json_data (rc->connection,
+                                       coin_ev_cs_json,
+                                       coin_ev_cs_spec);
+      GNUNET_JSON_parse_free (coin_ev_cs_json_spec);
+      if (GNUNET_OK != res)
+        return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
+      coin_ev_spec = coin_ev_cs_spec;
+      break;
+    default:
+      GNUNET_break (0);
+      GNUNET_JSON_parse_free (spec);
+      return TALER_MHD_reply_with_error (rc->connection,
+                                         MHD_HTTP_FORBIDDEN,
+                                         
TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
+                                         NULL);
+    }
+  }
+
+  {
+    if (0 >
+        TALER_amount_add (&wc.collectable.amount_with_fee,
+                          &dk->meta.value,
+                          &dk->meta.fee_withdraw))
+    {
+      GNUNET_JSON_parse_free (spec);
+      if (NULL != coin_ev_spec)
+        GNUNET_JSON_parse_free (coin_ev_spec);
+      return TALER_MHD_reply_with_error (rc->connection,
+                                         MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                         
TALER_EC_EXCHANGE_WITHDRAW_AMOUNT_FEE_OVERFLOW,
+                                         NULL);
+    }
+    TALER_amount_hton (&wc.wsrd.amount_with_fee,
+                       &wc.collectable.amount_with_fee);
   }
   TALER_amount_hton (&wc.wsrd.amount_with_fee,
                      &wc.collectable.amount_with_fee);
@@ -468,9 +554,30 @@ TEH_handler_withdraw (struct TEH_RequestContext *rc,
     = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW);
   wc.wsrd.h_denomination_pub
     = wc.collectable.denom_pub_hash;
-  TALER_coin_ev_hash (wc.blinded_msg,
-                      wc.blinded_msg_len,
-                      &wc.wsrd.h_coin_envelope);
+  switch (wc.blinded_planchet.cipher)
+  {
+  case TALER_DENOMINATION_RSA:
+    TALER_coin_ev_hash (
+      wc.blinded_planchet.details.rsa_blinded_planchet.blinded_msg,
+      wc.blinded_planchet.details.rsa_blinded_planchet.blinded_msg_size,
+      &wc.wsrd.h_coin_envelope);
+    break;
+  case TALER_DENOMINATION_CS:
+    TALER_coin_ev_hash (
+      &wc.blinded_planchet.details.cs_blinded_planchet,
+      sizeof (wc.blinded_planchet.details.cs_blinded_planchet),
+      &wc.wsrd.h_coin_envelope);
+    break;
+  default:
+    GNUNET_break (0);
+    GNUNET_JSON_parse_free (spec);
+    if (NULL != coin_ev_spec)
+      GNUNET_JSON_parse_free (coin_ev_spec);
+    return TALER_MHD_reply_with_error (rc->connection,
+                                       MHD_HTTP_FORBIDDEN,
+                                       
TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
+                                       NULL);
+  }
   if (GNUNET_OK !=
       GNUNET_CRYPTO_eddsa_verify (
         TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW,
@@ -481,23 +588,50 @@ TEH_handler_withdraw (struct TEH_RequestContext *rc,
     TALER_LOG_WARNING (
       "Client supplied invalid signature for withdraw request\n");
     GNUNET_JSON_parse_free (spec);
+    if (NULL != coin_ev_spec)
+      GNUNET_JSON_parse_free (coin_ev_spec);
     return TALER_MHD_reply_with_error (rc->connection,
                                        MHD_HTTP_FORBIDDEN,
                                        
TALER_EC_EXCHANGE_WITHDRAW_RESERVE_SIGNATURE_INVALID,
                                        NULL);
   }
 
+  // TODO: if CS: check nonce for reuse
+
   /* Sign before transaction! */
   ec = TALER_EC_NONE;
-  wc.collectable.sig
-    = TEH_keys_denomination_sign (&wc.collectable.denom_pub_hash,
-                                  wc.blinded_msg,
-                                  wc.blinded_msg_len,
-                                  &ec);
+  switch (wc.blinded_planchet.cipher)
+  {
+  case TALER_DENOMINATION_RSA:
+    wc.collectable.sig = TEH_keys_denomination_sign (
+      &wc.collectable.denom_pub_hash,
+      wc.blinded_planchet.details.rsa_blinded_planchet.blinded_msg,
+      wc.blinded_planchet.details.rsa_blinded_planchet.blinded_msg_size,
+      &ec);
+    break;
+  case TALER_DENOMINATION_CS:
+    wc.collectable.sig = TEH_keys_denomination_sign (
+      &wc.collectable.denom_pub_hash,
+      &wc.blinded_planchet.details.cs_blinded_planchet,
+      sizeof (wc.blinded_planchet.details.cs_blinded_planchet),
+      &ec);
+    break;
+  default:
+    GNUNET_break (0);
+    GNUNET_JSON_parse_free (spec);
+    if (NULL != coin_ev_spec)
+      GNUNET_JSON_parse_free (coin_ev_spec);
+    return TALER_MHD_reply_with_error (rc->connection,
+                                       MHD_HTTP_FORBIDDEN,
+                                       
TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
+                                       NULL);
+  }
   if (TALER_EC_NONE != ec)
   {
     GNUNET_break (0);
     GNUNET_JSON_parse_free (spec);
+    if (NULL != coin_ev_spec)
+      GNUNET_JSON_parse_free (coin_ev_spec);
     return TALER_MHD_reply_with_ec (rc->connection,
                                     ec,
                                     NULL);
@@ -519,12 +653,16 @@ TEH_handler_withdraw (struct TEH_RequestContext *rc,
          (or we might have done it optimistically above). */
       TALER_blinded_denom_sig_free (&wc.collectable.sig);
       GNUNET_JSON_parse_free (spec);
+      if (NULL != coin_ev_spec)
+        GNUNET_JSON_parse_free (coin_ev_spec);
       return mhd_ret;
     }
   }
 
   /* Clean up and send back final response */
   GNUNET_JSON_parse_free (spec);
+  if (NULL != coin_ev_spec)
+    GNUNET_JSON_parse_free (coin_ev_spec);
 
   {
     MHD_RESULT ret;
diff --git a/src/include/taler_testing_lib.h b/src/include/taler_testing_lib.h
index d5746c5c..c6bebbee 100644
--- a/src/include/taler_testing_lib.h
+++ b/src/include/taler_testing_lib.h
@@ -1332,6 +1332,30 @@ TALER_TESTING_cmd_withdraw_amount_reuse_key (
   unsigned int expected_response_code);
 
 
+/**
+ * Create a CS withdraw command, letting the caller specify
+ * the desired amount as string and also re-using an existing
+ * coin private key in the process (violating the specification,
+ * which will result in an error when spending the coin!).
+ *
+ * @param label command label.
+ * @param reserve_reference command providing us with a reserve to withdraw 
from
+ * @param amount how much we withdraw.
+ * @param coin_ref reference to (withdraw/reveal) command of a coin
+ *        from which we should re-use the private key
+ * @param expected_response_code which HTTP response code
+ *        we expect from the exchange.
+ * @return the withdraw command to be executed by the interpreter.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_withdraw_cs_amount_reuse_key (
+  const char *label,
+  const char *reserve_reference,
+  const char *amount,
+  const char *coin_ref,
+  unsigned int expected_response_code);
+
+
 /**
  * Create withdraw command, letting the caller specify the
  * amount by a denomination key.
diff --git a/src/json/json_helper.c b/src/json/json_helper.c
index c07129d1..6ee9c15a 100644
--- a/src/json/json_helper.c
+++ b/src/json/json_helper.c
@@ -388,6 +388,7 @@ parse_denom_sig (void *cls,
       }
       return GNUNET_OK;
     }
+  // TODO: case TALER_DENOMINATION_CS:
   default:
     GNUNET_break_op (0);
     return GNUNET_SYSERR;
@@ -483,6 +484,29 @@ parse_blinded_denom_sig (void *cls,
       }
       return GNUNET_OK;
     }
+  case TALER_DENOMINATION_CS:
+    {
+      struct GNUNET_JSON_Specification ispec[] = {
+        GNUNET_JSON_spec_uint32 ("b",
+                                 &denom_sig->details.blinded_cs_answer.b),
+        GNUNET_JSON_spec_fixed_auto ("s",
+                                     &denom_sig->details.blinded_cs_answer.
+                                     s_scalar),
+        GNUNET_JSON_spec_end ()
+      };
+
+      if (GNUNET_OK !=
+          GNUNET_JSON_parse (root,
+                             ispec,
+                             &emsg,
+                             &eline))
+      {
+        GNUNET_break_op (0);
+        return GNUNET_SYSERR;
+      }
+      return GNUNET_OK;
+    }
+    break;
   default:
     GNUNET_break_op (0);
     return GNUNET_SYSERR;
diff --git a/src/json/json_pack.c b/src/json/json_pack.c
index 86986718..cc147c4c 100644
--- a/src/json/json_pack.c
+++ b/src/json/json_pack.c
@@ -125,14 +125,21 @@ TALER_JSON_pack_blinded_denom_sig (
   switch (sig->cipher)
   {
   case TALER_DENOMINATION_RSA:
-    ps.object
-      = GNUNET_JSON_PACK (
-          GNUNET_JSON_pack_uint64 ("cipher",
-                                   TALER_DENOMINATION_RSA),
-          GNUNET_JSON_pack_rsa_signature ("blinded_rsa_signature",
-                                          sig->details.blinded_rsa_signature));
+    ps.object = GNUNET_JSON_PACK (
+      GNUNET_JSON_pack_uint64 ("cipher",
+                               TALER_DENOMINATION_RSA),
+      GNUNET_JSON_pack_rsa_signature ("blinded_rsa_signature",
+                                      sig->details.blinded_rsa_signature));
+    break;
+  case TALER_DENOMINATION_CS:
+    ps.object = GNUNET_JSON_PACK (
+      GNUNET_JSON_pack_uint64 ("cipher",
+                               TALER_DENOMINATION_CS),
+      GNUNET_JSON_pack_uint64 ("b",
+                               sig->details.blinded_cs_answer.b),
+      GNUNET_JSON_pack_data_auto ("s",
+                                  &sig->details.blinded_cs_answer.s_scalar));
     break;
-  // TODO: case TALER_DENOMINATION_CS:
   default:
     GNUNET_assert (0);
   }
diff --git a/src/lib/exchange_api_withdraw.c b/src/lib/exchange_api_withdraw.c
index 91838d4c..2c57797f 100644
--- a/src/lib/exchange_api_withdraw.c
+++ b/src/lib/exchange_api_withdraw.c
@@ -58,11 +58,21 @@ struct TALER_EXCHANGE_WithdrawHandle
    */
   void *cb_cls;
 
+  /**
+   * Reserve private key.
+   */
+  const struct TALER_ReservePrivateKeyP *reserve_priv;
+
   /**
    * Secrets of the planchet.
    */
   struct TALER_PlanchetSecretsP ps;
 
+  /**
+   * Details of the planchet.
+   */
+  struct TALER_PlanchetDetail pd;
+
   /**
    * Denomination key we are withdrawing.
    */
@@ -162,24 +172,44 @@ withdraw_cs_stage_two_callback (void *cls,
                                 const struct TALER_EXCHANGE_CsRResponse *csrr)
 {
   struct TALER_EXCHANGE_WithdrawHandle *wh = cls;
-  // TODO: this should only be set for non-OK cases
-  struct TALER_EXCHANGE_WithdrawResponse wr = {
-    .hr = csrr->hr
-  };
 
-  // switch (csrr->hr.http_status)
-  // {
-  // case MHD_HTTP_OK:
-  //   // TODO: implement rest of withdraw
-  //   break;
-  // default:
-  //   break;
-  // }
+  wh->csrh = NULL;
 
-  // TODO: this should only be called for non-OK cases
-  wh->cb (wh->cb_cls,
-          &wr);
-  TALER_EXCHANGE_withdraw_cancel (wh);
+  GNUNET_assert (TALER_DENOMINATION_CS == wh->pk.key.cipher);
+
+  switch (csrr->hr.http_status)
+  {
+  case MHD_HTTP_OK:
+    wh->ps.cs_r_pub = csrr->details.success.r_pubs;
+    TALER_blinding_secret_create (&wh->ps.blinding_key,
+                                  wh->pk.key.cipher,
+                                  &wh->ps.coin_priv,
+                                  &wh->ps.cs_r_pub);
+    if (GNUNET_OK !=
+        TALER_planchet_prepare (&wh->pk.key,
+                                &wh->ps,
+                                &wh->c_hash,
+                                &wh->pd))
+    {
+      GNUNET_break (0);
+      GNUNET_free (wh);
+    }
+    wh->wh2 = TALER_EXCHANGE_withdraw2 (wh->exchange,
+                                        &wh->pd,
+                                        wh->reserve_priv,
+                                        &handle_reserve_withdraw_finished,
+                                        wh);
+    break;
+  default:
+    // the CSR request went wrong -> serve response to the callback
+    struct TALER_EXCHANGE_WithdrawResponse wr = {
+      .hr = csrr->hr
+    };
+    wh->cb (wh->cb_cls,
+            &wr);
+    TALER_EXCHANGE_withdraw_cancel (wh);
+    break;
+  }
 }
 
 
@@ -210,16 +240,19 @@ TALER_EXCHANGE_withdraw (
   TALER_EXCHANGE_WithdrawCallback res_cb,
   void *res_cb_cls)
 {
-  struct TALER_PlanchetDetail pd;
   struct TALER_EXCHANGE_WithdrawHandle *wh;
 
   wh = GNUNET_new (struct TALER_EXCHANGE_WithdrawHandle);
   wh->exchange = exchange;
   wh->cb = res_cb;
   wh->cb_cls = res_cb_cls;
-  wh->pk = *pk;
+  wh->reserve_priv = reserve_priv;
   wh->ps = *ps;
+  wh->pk = *pk;
   wh->csrh = NULL;
+
+  TALER_denom_pub_deep_copy (&wh->pk.key,
+                             &pk->key);
   switch (pk->key.cipher)
   {
   case TALER_DENOMINATION_RSA:
@@ -227,27 +260,28 @@ TALER_EXCHANGE_withdraw (
         TALER_planchet_prepare (&pk->key,
                                 ps,
                                 &wh->c_hash,
-                                &pd))
+                                &wh->pd))
     {
       GNUNET_break (0);
       GNUNET_free (wh);
       return NULL;
     }
-    TALER_denom_pub_deep_copy (&wh->pk.key,
-                               &pk->key);
     wh->wh2 = TALER_EXCHANGE_withdraw2 (exchange,
-                                        &pd,
-                                        reserve_priv,
+                                        &wh->pd,
+                                        wh->reserve_priv,
                                         &handle_reserve_withdraw_finished,
                                         wh);
-    GNUNET_free (pd.blinded_planchet.details.rsa_blinded_planchet.blinded_msg);
+    GNUNET_free (
+      wh->pd.blinded_planchet.details.rsa_blinded_planchet.blinded_msg);
     return wh;
   case TALER_DENOMINATION_CS:
-    struct TALER_WithdrawNonce nonce;
-    TALER_cs_withdraw_nonce_derive (&ps->coin_priv, &nonce);
+    TALER_cs_withdraw_nonce_derive (&ps->coin_priv,
+                                    &wh->pd.blinded_planchet.details.
+                                    cs_blinded_planchet.nonce);
     wh->csrh = TALER_EXCHANGE_csr (exchange,
                                    pk,
-                                   &nonce,
+                                   &wh->pd.blinded_planchet.details.
+                                   cs_blinded_planchet.nonce,
                                    &withdraw_cs_stage_two_callback,
                                    wh);
     return wh;
diff --git a/src/lib/exchange_api_withdraw2.c b/src/lib/exchange_api_withdraw2.c
index c8eb3182..cb767e43 100644
--- a/src/lib/exchange_api_withdraw2.c
+++ b/src/lib/exchange_api_withdraw2.c
@@ -437,11 +437,26 @@ TALER_EXCHANGE_withdraw2 (
 
     TALER_amount_hton (&req.amount_with_fee,
                        &wh->requested_amount);
-    TALER_coin_ev_hash (
-      pd->blinded_planchet.details.rsa_blinded_planchet.blinded_msg,
-      pd->blinded_planchet.details.rsa_blinded_planchet.
-      blinded_msg_size,
-      &req.h_coin_envelope);
+    switch (dk->key.cipher)
+    {
+    case TALER_DENOMINATION_RSA:
+      TALER_coin_ev_hash (
+        pd->blinded_planchet.details.rsa_blinded_planchet.blinded_msg,
+        pd->blinded_planchet.details.rsa_blinded_planchet.
+        blinded_msg_size,
+        &req.h_coin_envelope);
+      break;
+    case TALER_DENOMINATION_CS:
+      TALER_coin_ev_hash (
+        &pd->blinded_planchet.details.cs_blinded_planchet,
+        sizeof (pd->blinded_planchet.details.cs_blinded_planchet),
+        &req.h_coin_envelope);
+      break;
+    default:
+      GNUNET_break (0);
+      GNUNET_free (wh);
+      return NULL;
+    }
     GNUNET_CRYPTO_eddsa_sign (&reserve_priv->eddsa_priv,
                               &req,
                               &reserve_sig.eddsa_signature);
@@ -449,17 +464,44 @@ TALER_EXCHANGE_withdraw2 (
 
   {
     json_t *withdraw_obj;
-
-    withdraw_obj = GNUNET_JSON_PACK (
-      GNUNET_JSON_pack_data_auto ("denom_pub_hash",
-                                  &pd->denom_pub_hash),
-      GNUNET_JSON_pack_data_varsize ("coin_ev",
-                                     pd->blinded_planchet.details.
-                                     rsa_blinded_planchet.blinded_msg,
-                                     pd->blinded_planchet.details.
-                                     rsa_blinded_planchet.blinded_msg_size),
-      GNUNET_JSON_pack_data_auto ("reserve_sig",
-                                  &reserve_sig));
+    switch (dk->key.cipher)
+    {
+    case TALER_DENOMINATION_RSA:
+      withdraw_obj = GNUNET_JSON_PACK (
+        GNUNET_JSON_pack_data_auto ("denom_pub_hash",
+                                    &pd->denom_pub_hash),
+        GNUNET_JSON_pack_data_varsize ("coin_ev",
+                                       pd->blinded_planchet.details.
+                                       rsa_blinded_planchet.blinded_msg,
+                                       pd->blinded_planchet.details.
+                                       rsa_blinded_planchet.blinded_msg_size),
+        GNUNET_JSON_pack_data_auto ("reserve_sig",
+                                    &reserve_sig));
+      break;
+    case TALER_DENOMINATION_CS:
+      json_t *coin_ev_object = GNUNET_JSON_PACK (
+        GNUNET_JSON_pack_data_auto ("nonce",
+                                    &pd->blinded_planchet.details.
+                                    cs_blinded_planchet.nonce),
+        GNUNET_JSON_pack_data_auto ("c0",
+                                    &pd->blinded_planchet.details.
+                                    cs_blinded_planchet.c[0]),
+        GNUNET_JSON_pack_data_auto ("c1",
+                                    &pd->blinded_planchet.details.
+                                    cs_blinded_planchet.c[1]));
+      withdraw_obj = GNUNET_JSON_PACK (
+        GNUNET_JSON_pack_data_auto ("denom_pub_hash",
+                                    &pd->denom_pub_hash),
+        GNUNET_JSON_pack_object_steal ("coin_ev",
+                                       coin_ev_object),
+        GNUNET_JSON_pack_data_auto ("reserve_sig",
+                                    &reserve_sig));
+      break;
+    default:
+      GNUNET_break (0);
+      GNUNET_free (wh);
+      return NULL;
+    }
     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                 "Attempting to withdraw from reserve %s\n",
                 TALER_B2S (&wh->reserve_pub));
diff --git a/src/pq/pq_query_helper.c b/src/pq/pq_query_helper.c
index c04161d0..ca1e94ef 100644
--- a/src/pq/pq_query_helper.c
+++ b/src/pq/pq_query_helper.c
@@ -290,7 +290,9 @@ qconv_denom_sig (void *cls,
       denom_sig->details.rsa_signature,
       &tbuf);
     break;
-  // TODO: add case for Clause-Schnorr
+  case TALER_DENOMINATION_CS:
+    tlen = sizeof (denom_sig->details.cs_signature);
+    break;
   default:
     GNUNET_assert (0);
   }
@@ -307,7 +309,11 @@ qconv_denom_sig (void *cls,
             tlen);
     GNUNET_free (tbuf);
     break;
-  // TODO: add case for Clause-Schnorr
+  case TALER_DENOMINATION_CS:
+    memcpy (&buf[sizeof (be)],
+            &denom_sig->details.cs_signature,
+            tlen);
+    break;
   default:
     GNUNET_assert (0);
   }
@@ -380,7 +386,9 @@ qconv_blinded_denom_sig (void *cls,
       denom_sig->details.blinded_rsa_signature,
       &tbuf);
     break;
-  // TODO: add case for Clause-Schnorr
+  case TALER_DENOMINATION_CS:
+    tlen = sizeof (denom_sig->details.blinded_cs_answer);
+    break;
   default:
     GNUNET_assert (0);
   }
@@ -397,7 +405,11 @@ qconv_blinded_denom_sig (void *cls,
             tlen);
     GNUNET_free (tbuf);
     break;
-  // TODO: add case for Clause-Schnorr
+  case TALER_DENOMINATION_CS:
+    memcpy (&buf[sizeof (be)],
+            &denom_sig->details.blinded_cs_answer,
+            tlen);
+    break;
   default:
     GNUNET_assert (0);
   }
diff --git a/src/pq/pq_result_helper.c b/src/pq/pq_result_helper.c
index d6b0eb7b..2009f0e3 100644
--- a/src/pq/pq_result_helper.c
+++ b/src/pq/pq_result_helper.c
@@ -670,7 +670,16 @@ extract_blinded_denom_sig (void *cls,
       return GNUNET_SYSERR;
     }
     return GNUNET_OK;
-  // FIXME: add CS case!
+  case TALER_DENOMINATION_CS:
+    if (sizeof (sig->details.blinded_cs_answer) != len)
+    {
+      GNUNET_break (0);
+      return GNUNET_SYSERR;
+    }
+    memcpy (&sig->details.blinded_cs_answer,
+            res,
+            len);
+    return GNUNET_OK;
   default:
     GNUNET_break (0);
   }
diff --git a/src/testing/test_exchange_api.c b/src/testing/test_exchange_api.c
index 29a3e5c6..ba293d4b 100644
--- a/src/testing/test_exchange_api.c
+++ b/src/testing/test_exchange_api.c
@@ -413,49 +413,49 @@ run (void *cls,
     /**
      * Move money to the exchange's bank account.
      */
-    CMD_TRANSFER_TO_EXCHANGE ("create-reserve-1",
+    CMD_TRANSFER_TO_EXCHANGE ("create-reserve-cs-1",
                               "EUR:6.02"),
-    TALER_TESTING_cmd_check_bank_admin_transfer ("check-create-reserve-1",
+    TALER_TESTING_cmd_check_bank_admin_transfer ("check-create-reserve-cs-1",
                                                  "EUR:6.02",
                                                  bc.user42_payto,
                                                  bc.exchange_payto,
-                                                 "create-reserve-1"),
+                                                 "create-reserve-cs-1"),
     /**
      * Make a reserve exist, according to the previous
      * transfer.
      */
-    CMD_EXEC_WIREWATCH ("wirewatch-1"),
+    CMD_EXEC_WIREWATCH ("wirewatch-cs-1"),
     /**
      * Withdraw EUR:5.
      */
     TALER_TESTING_cmd_withdraw_cs_amount ("withdraw-cs-coin-1",
-                                          "create-reserve-1",
+                                          "create-reserve-cs-1",
                                           "EUR:5",
                                           MHD_HTTP_OK),
-    // TODO: rest of the tests
-    // /**
-    //  * Withdraw EUR:1 using the SAME private coin key as for the previous 
coin
-    //  * (in violation of the specification, to be detected on spending!).
-    //  */
-    // TALER_TESTING_cmd_withdraw_amount_reuse_key ("withdraw-coin-1x",
-    //                                              "create-reserve-1",
-    //                                              "EUR:1",
-    //                                              "withdraw-coin-1",
-    //                                              MHD_HTTP_OK),
-    // /**
-    //  * Check the reserve is depleted.
-    //  */
-    // TALER_TESTING_cmd_status ("status-1",
-    //                           "create-reserve-1",
-    //                           "EUR:0",
-    //                           MHD_HTTP_OK),
-    // /*
-    //  * Try to overdraw.
-    //  */
-    // TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-2",
-    //                                    "create-reserve-1",
-    //                                    "EUR:5",
-    //                                    MHD_HTTP_CONFLICT),
+    /**
+     * Withdraw EUR:1 using the SAME private coin key as for the previous coin
+     * (in violation of the specification, to be detected on spending!).
+     */
+    TALER_TESTING_cmd_withdraw_cs_amount_reuse_key ("withdraw-cs-coin-1x",
+                                                    "create-reserve-cs-1",
+                                                    "EUR:1",
+                                                    "withdraw-cs-coin-1",
+                                                    MHD_HTTP_OK),
+    /**
+     * Check the reserve is depleted.
+     */
+    TALER_TESTING_cmd_status ("status-cs-1",
+                              "create-reserve-cs-1",
+                              "EUR:0",
+                              MHD_HTTP_OK),
+    /*
+     * Try to overdraw.
+     */
+    TALER_TESTING_cmd_withdraw_cs_amount ("withdraw-cs-coin-2",
+                                          "create-reserve-cs-1",
+                                          "EUR:5",
+                                          MHD_HTTP_CONFLICT),
+    // TODO: add test for nonce reuse
     TALER_TESTING_cmd_end ()
   };
 
diff --git a/src/testing/testing_api_cmd_withdraw.c 
b/src/testing/testing_api_cmd_withdraw.c
index e07eac34..2a98765f 100644
--- a/src/testing/testing_api_cmd_withdraw.c
+++ b/src/testing/testing_api_cmd_withdraw.c
@@ -266,13 +266,6 @@ reserve_withdraw_cb (void *cls,
   switch (wr->hr.http_status)
   {
   case MHD_HTTP_OK:
-    // TODO: remove
-    // temporary make test successful when CS
-    if (TALER_DENOMINATION_CS == ws->cipher)
-    {
-      break;
-    }
-
     TALER_denom_sig_deep_copy (&ws->sig,
                                &wr->details.success.sig);
     if (0 != ws->total_backoff.rel_value_us)
@@ -661,6 +654,8 @@ TALER_TESTING_cmd_withdraw_amount_reuse_key (
   const char *coin_ref,
   unsigned int expected_response_code)
 {
+  // TODO: ATM this is hardcoded to RSA denominations
+  // (use TALER_TESTING_cmd_withdraw_cs_amount for Clause Schnorr)
   struct TALER_TESTING_Command cmd;
 
   cmd = TALER_TESTING_cmd_withdraw_amount (label,
@@ -676,6 +671,29 @@ TALER_TESTING_cmd_withdraw_amount_reuse_key (
 }
 
 
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_withdraw_cs_amount_reuse_key (
+  const char *label,
+  const char *reserve_reference,
+  const char *amount,
+  const char *coin_ref,
+  unsigned int expected_response_code)
+{
+  struct TALER_TESTING_Command cmd;
+
+  cmd = TALER_TESTING_cmd_withdraw_cs_amount (label,
+                                              reserve_reference,
+                                              amount,
+                                              expected_response_code);
+  {
+    struct WithdrawState *ws = cmd.cls;
+
+    ws->reuse_coin_key_ref = coin_ref;
+  }
+  return cmd;
+}
+
+
 /**
  * Create withdraw command, letting the caller specify the
  * amount by a denomination key.

-- 
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]