exchange

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

testing_api_cmd_reserve_attest.c (7200B)


      1 /*
      2   This file is part of TALER
      3   Copyright (C) 2014-2022 Taler Systems SA
      4 
      5   TALER is free software; you can redistribute it and/or modify
      6   it under the terms of the GNU General Public License as
      7   published by the Free Software Foundation; either version 3, or
      8   (at your option) any later version.
      9 
     10   TALER is distributed in the hope that it will be useful, but
     11   WITHOUT ANY WARRANTY; without even the implied warranty of
     12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13   GNU General Public License for more details.
     14 
     15   You should have received a copy of the GNU General Public
     16   License along with TALER; see the file COPYING.  If not, see
     17   <http://www.gnu.org/licenses/>
     18 */
     19 /**
     20  * @file testing/testing_api_cmd_reserve_attest.c
     21  * @brief Implement the /reserve/$RID/attest test command.
     22  * @author Christian Grothoff
     23  */
     24 #include "taler/taler_json_lib.h"
     25 #include <gnunet/gnunet_curl_lib.h>
     26 struct AttestState;
     27 #define TALER_EXCHANGE_POST_RESERVES_ATTEST_RESULT_CLOSURE struct AttestState
     28 #include "taler/exchange/post-reserves-attest-RESERVE_PUB.h"
     29 #include "taler/taler_testing_lib.h"
     30 
     31 /**
     32  * State for a "attest" CMD.
     33  */
     34 struct AttestState
     35 {
     36   /**
     37    * Label to the command which created the reserve to check,
     38    * needed to resort the reserve key.
     39    */
     40   const char *reserve_reference;
     41 
     42   /**
     43    * Handle to the "reserve attest" operation.
     44    */
     45   struct TALER_EXCHANGE_PostReservesAttestHandle *rsh;
     46 
     47   /**
     48    * Private key of the reserve being analyzed.
     49    */
     50   const struct TALER_ReservePrivateKeyP *reserve_priv;
     51 
     52   /**
     53    * Public key of the reserve being analyzed.
     54    */
     55   struct TALER_ReservePublicKeyP reserve_pub;
     56 
     57   /**
     58    * Array of attributes to request, of length @e attrs_len.
     59    */
     60   const char **attrs;
     61 
     62   /**
     63    * Length of the @e attrs array.
     64    */
     65   unsigned int attrs_len;
     66 
     67   /**
     68    * Expected HTTP response code.
     69    */
     70   unsigned int expected_response_code;
     71 
     72   /**
     73    * Interpreter state.
     74    */
     75   struct TALER_TESTING_Interpreter *is;
     76 
     77   /* FIXME: expose fields below as traits... */
     78 
     79   /**
     80    * Attested attributes returned by the exchange.
     81    */
     82   json_t *attributes;
     83 
     84   /**
     85    * Expiration time of the attested attributes.
     86    */
     87   struct GNUNET_TIME_Timestamp expiration_time;
     88 
     89   /**
     90    * Signature by the exchange affirming the attributes.
     91    */
     92   struct TALER_ExchangeSignatureP exchange_sig;
     93 
     94   /**
     95    * Online signing key used by the exchange.
     96    */
     97   struct TALER_ExchangePublicKeyP exchange_pub;
     98 };
     99 
    100 
    101 /**
    102  * Check that the reserve balance and HTTP response code are
    103  * both acceptable.
    104  *
    105  * @param ss closure.
    106  * @param rs HTTP response details
    107  */
    108 static void
    109 reserve_attest_cb (
    110   struct AttestState *ss,
    111   const struct TALER_EXCHANGE_PostReservesAttestResponse *rs)
    112 {
    113   struct TALER_TESTING_Interpreter *is = ss->is;
    114 
    115   ss->rsh = NULL;
    116   if (ss->expected_response_code != rs->hr.http_status)
    117   {
    118     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    119                 "Unexpected HTTP response code: %d in %s:%u\n",
    120                 rs->hr.http_status,
    121                 __FILE__,
    122                 __LINE__);
    123     json_dumpf (rs->hr.reply,
    124                 stderr,
    125                 JSON_INDENT (2));
    126     TALER_TESTING_interpreter_fail (ss->is);
    127     return;
    128   }
    129   if (MHD_HTTP_OK != rs->hr.http_status)
    130   {
    131     TALER_TESTING_interpreter_next (is);
    132     return;
    133   }
    134   ss->attributes = json_incref ((json_t*) rs->details.ok.attributes);
    135   ss->expiration_time = rs->details.ok.expiration_time;
    136   ss->exchange_pub = rs->details.ok.exchange_pub;
    137   ss->exchange_sig = rs->details.ok.exchange_sig;
    138   TALER_TESTING_interpreter_next (is);
    139 }
    140 
    141 
    142 /**
    143  * Run the command.
    144  *
    145  * @param cls closure.
    146  * @param cmd the command being executed.
    147  * @param is the interpreter state.
    148  */
    149 static void
    150 attest_run (void *cls,
    151             const struct TALER_TESTING_Command *cmd,
    152             struct TALER_TESTING_Interpreter *is)
    153 {
    154   struct AttestState *ss = cls;
    155   const struct TALER_TESTING_Command *create_reserve;
    156   const char *exchange_url;
    157 
    158   ss->is = is;
    159   exchange_url = TALER_TESTING_get_exchange_url (is);
    160   if (NULL == exchange_url)
    161   {
    162     GNUNET_break (0);
    163     return;
    164   }
    165   create_reserve
    166     = TALER_TESTING_interpreter_lookup_command (is,
    167                                                 ss->reserve_reference);
    168 
    169   if (NULL == create_reserve)
    170   {
    171     GNUNET_break (0);
    172     TALER_TESTING_interpreter_fail (is);
    173     return;
    174   }
    175   if (GNUNET_OK !=
    176       TALER_TESTING_get_trait_reserve_priv (create_reserve,
    177                                             &ss->reserve_priv))
    178   {
    179     GNUNET_break (0);
    180     TALER_LOG_ERROR ("Failed to find reserve_priv for attest query\n");
    181     TALER_TESTING_interpreter_fail (is);
    182     return;
    183   }
    184   GNUNET_CRYPTO_eddsa_key_get_public (&ss->reserve_priv->eddsa_priv,
    185                                       &ss->reserve_pub.eddsa_pub);
    186   ss->rsh = TALER_EXCHANGE_post_reserves_attest_create (
    187     TALER_TESTING_interpreter_get_context (is),
    188     exchange_url,
    189     TALER_TESTING_get_keys (is),
    190     ss->reserve_priv,
    191     ss->attrs_len,
    192     ss->attrs);
    193   if (NULL == ss->rsh)
    194   {
    195     GNUNET_break (0);
    196     TALER_TESTING_interpreter_fail (is);
    197     return;
    198   }
    199   {
    200     enum TALER_ErrorCode ec;
    201 
    202     ec = TALER_EXCHANGE_post_reserves_attest_start (ss->rsh,
    203                                                     &reserve_attest_cb,
    204                                                     ss);
    205     if (TALER_EC_NONE != ec)
    206     {
    207       GNUNET_break (0);
    208       ss->rsh = NULL;
    209       TALER_TESTING_interpreter_fail (is);
    210       return;
    211     }
    212   }
    213 }
    214 
    215 
    216 /**
    217  * Cleanup the state from a "reserve attest" CMD, and possibly
    218  * cancel a pending operation thereof.
    219  *
    220  * @param cls closure.
    221  * @param cmd the command which is being cleaned up.
    222  */
    223 static void
    224 attest_cleanup (void *cls,
    225                 const struct TALER_TESTING_Command *cmd)
    226 {
    227   struct AttestState *ss = cls;
    228 
    229   if (NULL != ss->rsh)
    230   {
    231     TALER_TESTING_command_incomplete (ss->is,
    232                                       cmd->label);
    233     TALER_EXCHANGE_post_reserves_attest_cancel (ss->rsh);
    234     ss->rsh = NULL;
    235   }
    236   json_decref (ss->attributes);
    237   GNUNET_free (ss->attrs);
    238   GNUNET_free (ss);
    239 }
    240 
    241 
    242 struct TALER_TESTING_Command
    243 TALER_TESTING_cmd_reserve_attest (const char *label,
    244                                   const char *reserve_reference,
    245                                   unsigned int expected_response_code,
    246                                   ...)
    247 {
    248   struct AttestState *ss;
    249   unsigned int num_args;
    250   const char *ea;
    251   va_list ap;
    252 
    253   num_args = 0;
    254   va_start (ap, expected_response_code);
    255   while (NULL != va_arg (ap, const char *))
    256     num_args++;
    257   va_end (ap);
    258 
    259   GNUNET_assert (NULL != reserve_reference);
    260   ss = GNUNET_new (struct AttestState);
    261   ss->reserve_reference = reserve_reference;
    262   ss->expected_response_code = expected_response_code;
    263   ss->attrs_len = num_args;
    264   ss->attrs = GNUNET_new_array (num_args,
    265                                 const char *);
    266   num_args = 0;
    267   va_start (ap, expected_response_code);
    268   while (NULL != (ea = va_arg (ap, const char *)))
    269     ss->attrs[num_args++] = ea;
    270   va_end (ap);
    271 
    272   {
    273     struct TALER_TESTING_Command cmd = {
    274       .cls = ss,
    275       .label = label,
    276       .run = &attest_run,
    277       .cleanup = &attest_cleanup
    278     };
    279 
    280     return cmd;
    281   }
    282 }