anastasis

Credential backup and recovery protocol and service
Log | Files | Refs | Submodules | README | LICENSE

testing_api_cmd_policy_store.c (9756B)


      1 /*
      2   This file is part of ANASTASIS
      3   Copyright (C) 2014-2019 Anastasis SARL
      4 
      5   ANASTASIS 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   ANASTASIS 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 ANASTASIS; see the file COPYING.  If not, see
     17   <http://www.gnu.org/licenses/>
     18 */
     19 
     20 /**
     21  * @file testing/testing_api_cmd_policy_store.c
     22  * @brief command to execute the anastasis backend service.
     23  * @author Christian Grothoff
     24  * @author Dominik Meister
     25  * @author Dennis Neufeld
     26  */
     27 
     28 #include "platform.h"
     29 #include "anastasis_testing_lib.h"
     30 #include <taler/taler_util.h>
     31 #include <taler/taler_testing_lib.h>
     32 #include <taler/taler_merchant_service.h>
     33 
     34 
     35 /**
     36  * State for a "policy store" CMD.
     37  */
     38 struct PolicyStoreState
     39 {
     40   /**
     41    * Claim token we got back, if any. Otherwise all zeros.
     42    */
     43   struct TALER_ClaimTokenP claim_token;
     44 
     45   /**
     46    * The policy data.
     47    */
     48   const void *recovery_data;
     49 
     50   /**
     51    * Number of bytes in @e recovery_data
     52    */
     53   size_t recovery_data_size;
     54 
     55   /**
     56    * Expected status code.
     57    */
     58   unsigned int http_status;
     59 
     60   /**
     61    * Eddsa Publickey.
     62    */
     63   struct ANASTASIS_CRYPTO_AccountPublicKeyP anastasis_pub;
     64 
     65   /**
     66    * Eddsa Privatekey.
     67    */
     68   struct ANASTASIS_CRYPTO_AccountPrivateKeyP anastasis_priv;
     69 
     70   /**
     71    * Hash of uploaded data, used to verify the response.
     72    */
     73   struct GNUNET_HashCode curr_hash;
     74 
     75   /**
     76    * The /policy POST operation handle.
     77    */
     78   struct ANASTASIS_PolicyStoreOperation *pso;
     79 
     80   /**
     81    * The nonce.
     82    */
     83   struct ANASTASIS_CRYPTO_NonceP nonce;
     84 
     85   /**
     86    * URL of the anastasis backend.
     87    */
     88   const char *anastasis_url;
     89 
     90   /**
     91    * The interpreter state.
     92    */
     93   struct TALER_TESTING_Interpreter *is;
     94 
     95   /**
     96    * Previous upload, or NULL for none. Used to calculate what THIS
     97    * upload is based on.
     98    */
     99   const char *prev_upload;
    100 
    101   /**
    102    * Payment order ID we are to provide in the request, or zero.
    103    */
    104   struct ANASTASIS_PaymentSecretP payment_secret_request;
    105 
    106   /**
    107    * The order ID, for making the payment.
    108    */
    109   char *order_id;
    110 
    111   /**
    112    * Payment order ID we are to provide in the response, or zero.
    113    */
    114   struct ANASTASIS_PaymentSecretP payment_secret_response;
    115 
    116   /**
    117    * Options for how we are supposed to do the upload.
    118    */
    119   enum ANASTASIS_TESTING_PolicyStoreOption psopt;
    120 
    121   /**
    122    * True if @e payment_secret_request is initialized.
    123    */
    124   bool payment_secret_set;
    125 };
    126 
    127 /**
    128  * Function called with the results of an #ANASTASIS_policy_store() operation.
    129  *
    130  * @param cls closure
    131  * @param ud details about the upload operation
    132  */
    133 static void
    134 policy_store_cb (void *cls,
    135                  const struct ANASTASIS_UploadDetails *ud)
    136 {
    137   struct PolicyStoreState *pss = cls;
    138 
    139   pss->pso = NULL;
    140   if (ud->http_status != pss->http_status)
    141   {
    142     TALER_TESTING_unexpected_status (pss->is,
    143                                      ud->http_status,
    144                                      pss->http_status);
    145     return;
    146   }
    147   switch (ud->us)
    148   {
    149   case ANASTASIS_US_SUCCESS:
    150     if (0 != GNUNET_memcmp (&pss->curr_hash,
    151                             ud->details.success.curr_backup_hash))
    152     {
    153       GNUNET_break (0);
    154       TALER_TESTING_interpreter_fail (pss->is);
    155       return;
    156     }
    157     break;
    158   case ANASTASIS_US_PAYMENT_REQUIRED:
    159     pss->payment_secret_response = ud->details.payment.ps;
    160     {
    161       struct TALER_MERCHANT_PayUriData pd;
    162 
    163       if (GNUNET_OK !=
    164           TALER_MERCHANT_parse_pay_uri (ud->details.payment.payment_request,
    165                                         &pd))
    166       {
    167         GNUNET_break (0);
    168         TALER_TESTING_interpreter_fail (pss->is);
    169         return;
    170       }
    171       pss->order_id = GNUNET_strdup (pd.order_id);
    172       if (NULL != pd.claim_token)
    173         pss->claim_token = *pd.claim_token;
    174       TALER_MERCHANT_parse_pay_uri_free (&pd);
    175     }
    176     break;
    177   case ANASTASIS_US_HTTP_ERROR:
    178     break;
    179   case ANASTASIS_US_CLIENT_ERROR:
    180     GNUNET_break (0);
    181     TALER_TESTING_interpreter_fail (pss->is);
    182     return;
    183   case ANASTASIS_US_SERVER_ERROR:
    184     GNUNET_break (0);
    185     TALER_TESTING_interpreter_fail (pss->is);
    186     return;
    187   default:
    188     GNUNET_break (0);
    189     TALER_TESTING_interpreter_fail (pss->is);
    190     return;
    191   }
    192   TALER_TESTING_interpreter_next (pss->is);
    193 }
    194 
    195 
    196 /**
    197  * Run a "policy store" CMD.
    198  *
    199  * @param cls closure.
    200  * @param cmd command currently being run.
    201  * @param is interpreter state.
    202  */
    203 static void
    204 policy_store_run (void *cls,
    205                   const struct TALER_TESTING_Command *cmd,
    206                   struct TALER_TESTING_Interpreter *is)
    207 {
    208   struct PolicyStoreState *pss = cls;
    209 
    210   pss->is = is;
    211   if (NULL != pss->prev_upload)
    212   {
    213     const struct TALER_TESTING_Command *ref;
    214 
    215     ref = TALER_TESTING_interpreter_lookup_command (is,
    216                                                     pss->prev_upload);
    217     if (NULL == ref)
    218     {
    219       GNUNET_break (0);
    220       TALER_TESTING_interpreter_fail (pss->is);
    221       return;
    222     }
    223     {
    224       const struct ANASTASIS_CRYPTO_AccountPrivateKeyP *priv;
    225 
    226       if (GNUNET_OK !=
    227           ANASTASIS_TESTING_get_trait_account_priv (ref,
    228                                                     &priv))
    229       {
    230         GNUNET_break (0);
    231         TALER_TESTING_interpreter_fail (pss->is);
    232         return;
    233       }
    234       pss->anastasis_priv = *priv;
    235     }
    236     {
    237       const struct ANASTASIS_CRYPTO_AccountPublicKeyP *pub;
    238 
    239       if (GNUNET_OK !=
    240           ANASTASIS_TESTING_get_trait_account_pub (ref,
    241                                                    &pub))
    242       {
    243         GNUNET_break (0);
    244         TALER_TESTING_interpreter_fail (pss->is);
    245         return;
    246       }
    247       pss->anastasis_pub = *pub;
    248     }
    249     {
    250       const struct ANASTASIS_PaymentSecretP *ps;
    251 
    252       if (GNUNET_OK !=
    253           ANASTASIS_TESTING_get_trait_payment_secret (ref,
    254                                                       &ps))
    255       {
    256         GNUNET_break (0);
    257         TALER_TESTING_interpreter_fail (pss->is);
    258         return;
    259       }
    260       pss->payment_secret_request = *ps;
    261       pss->payment_secret_set = true;
    262     }
    263   }
    264   else
    265   {
    266     GNUNET_CRYPTO_eddsa_key_create (&pss->anastasis_priv.priv);
    267     GNUNET_CRYPTO_eddsa_key_get_public (&pss->anastasis_priv.priv,
    268                                         &pss->anastasis_pub.pub);
    269   }
    270 
    271   GNUNET_CRYPTO_hash (pss->recovery_data,
    272                       pss->recovery_data_size,
    273                       &pss->curr_hash);
    274   pss->pso = ANASTASIS_policy_store (
    275     TALER_TESTING_interpreter_get_context (is),
    276     pss->anastasis_url,
    277     &pss->anastasis_priv,
    278     pss->recovery_data,
    279     pss->recovery_data_size,
    280     "metadata", strlen ("metadata"),
    281     (0 != (ANASTASIS_TESTING_PSO_REQUEST_PAYMENT & pss->psopt)),
    282     pss->payment_secret_set ? &pss->payment_secret_request : NULL,
    283     GNUNET_TIME_UNIT_ZERO,
    284     &policy_store_cb,
    285     pss);
    286   if (NULL == pss->pso)
    287   {
    288     GNUNET_break (0);
    289     TALER_TESTING_interpreter_fail (pss->is);
    290     return;
    291   }
    292 }
    293 
    294 
    295 /**
    296  * Free the state of a "policy store" CMD, and possibly
    297  * cancel it if it did not complete.
    298  *
    299  * @param cls closure.
    300  * @param cmd command being freed.
    301  */
    302 static void
    303 policy_store_cleanup (void *cls,
    304                       const struct TALER_TESTING_Command *cmd)
    305 {
    306   struct PolicyStoreState *pss = cls;
    307 
    308   if (NULL != pss->pso)
    309   {
    310     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
    311                 "Command '%s' did not complete (policy post)\n",
    312                 cmd->label);
    313     ANASTASIS_policy_store_cancel (pss->pso);
    314     pss->pso = NULL;
    315   }
    316   GNUNET_free (pss->order_id);
    317   GNUNET_free (pss);
    318 }
    319 
    320 
    321 /**
    322  * Offer internal data to other commands.
    323  *
    324  * @param cls closure
    325  * @param[out] ret result (could be anything)
    326  * @param trait name of the trait
    327  * @param index index number of the object to extract.
    328  * @return #GNUNET_OK on success
    329  */
    330 static int
    331 policy_store_traits (void *cls,
    332                      const void **ret,
    333                      const char *trait,
    334                      unsigned int index)
    335 {
    336   struct PolicyStoreState *pss = cls;
    337   struct TALER_TESTING_Trait traits[] = {
    338     TALER_TESTING_make_trait_claim_token (&pss->claim_token),
    339     TALER_TESTING_make_trait_order_id (pss->order_id),
    340     ANASTASIS_TESTING_make_trait_hash (&pss->curr_hash),
    341     ANASTASIS_TESTING_make_trait_account_pub (&pss->anastasis_pub),
    342     ANASTASIS_TESTING_make_trait_account_priv (&pss->anastasis_priv),
    343     ANASTASIS_TESTING_make_trait_payment_secret (&pss->payment_secret_response),
    344     TALER_TESTING_trait_end ()
    345   };
    346 
    347   return TALER_TESTING_get_trait (traits,
    348                                   ret,
    349                                   trait,
    350                                   index);
    351 }
    352 
    353 
    354 struct TALER_TESTING_Command
    355 ANASTASIS_TESTING_cmd_policy_store (
    356   const char *label,
    357   const char *anastasis_url,
    358   const char *prev_upload,
    359   unsigned int http_status,
    360   enum ANASTASIS_TESTING_PolicyStoreOption pso,
    361   const void *recovery_data,
    362   size_t recovery_data_size)
    363 {
    364   struct PolicyStoreState *pss;
    365 
    366   pss = GNUNET_new (struct PolicyStoreState);
    367   pss->recovery_data = recovery_data;
    368   pss->recovery_data_size = recovery_data_size;
    369   pss->http_status = http_status;
    370   pss->psopt = pso;
    371   pss->anastasis_url = anastasis_url;
    372   pss->prev_upload = prev_upload;
    373   {
    374     struct TALER_TESTING_Command cmd = {
    375       .cls = pss,
    376       .label = label,
    377       .run = &policy_store_run,
    378       .cleanup = &policy_store_cleanup,
    379       .traits = &policy_store_traits
    380     };
    381 
    382     return cmd;
    383   }
    384 }