frosix

Multiparty signature service (experimental)
Log | Files | Refs | README | LICENSE

frosix_api_request-challenge.c (9171B)


      1 /*
      2   This file is part of Frosix
      3   Copyright (C) 2020, 2021 Anastasis SARL
      4 
      5   Frosix is free software; you can redistribute it and/or modify it under the
      6   terms of the GNU General Public License as published by the Free Software
      7   Foundation; either version 3, or (at your option) any later version.
      8 
      9   Frosix is distributed in the hope that it will be useful, but WITHOUT ANY
     10   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     11   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
     12 
     13   You should have received a copy of the GNU General Public License along with
     14   Frosix; see the file COPYING.GPL.  If not, see <http://www.gnu.org/licenses/>
     15 */
     16 /**
     17  * @file reducer/frosix_api_authenticate.c
     18  * @brief frosix reducer sign api
     19  * @author Christian Grothoff
     20  * @author Dominik Meister
     21  * @author Dennis Neufeld
     22  * @author Joel Urech
     23  */
     24 
     25 #include "platform.h"
     26 #include "frost_verify.h"
     27 #include "frosix.h"
     28 #include "frosix_api.h"
     29 #include <taler/taler_merchant_service.h>
     30 
     31 
     32 /**
     33  * FIXME
     34 */
     35 struct FROSIX_Provider
     36 {
     37   /**
     38    * URL of the provider.
     39   */
     40   char *backend_url;
     41 
     42   /**
     43    * Index of the provider
     44   */
     45   uint8_t provider_index;
     46 
     47   /**
     48    * Authentication method.
     49   */
     50   char *auth_method;
     51 
     52   /**
     53    * Authentication data.
     54   */
     55   char *auth_data;
     56 
     57   /**
     58    * Salt for the hash of the authentication data
     59   */
     60   struct GNUNET_HashCode auth_nonce;
     61 
     62   /**
     63    * Encryption key
     64   */
     65   struct FROSIX_EncryptionKey enc_key;
     66 };
     67 
     68 /**
     69  * Struct to store all parsed data from the cli and /config and /seed
     70 */
     71 struct FROSIX_ChallengeRequestData
     72 {
     73   /**
     74    * Our hashed message.
     75   */
     76   struct FROST_MessageHash message_hash;
     77 
     78   /**
     79    * Our provider
     80   */
     81   struct FROSIX_Provider provider;
     82 };
     83 
     84 /**
     85  * State of a challenge request procedure
     86 */
     87 struct FROSIX_ChallengeRequestState
     88 {
     89   /**
     90    * State we are updating.
     91    */
     92   struct FROSIX_ChallengeRequestData *challenge_data;
     93 
     94   /**
     95    * Function to call when we are done.
     96    */
     97   FROSIX_ActionCallback cb;
     98 
     99   /**
    100    * Closure for @e cb.
    101    */
    102   void *cb_cls;
    103 
    104   /**
    105    * Redux action we returned to our controller.
    106    */
    107   struct FROSIX_ReduxAction ra;
    108 
    109   /**
    110    * Last error code
    111   */
    112   enum TALER_ErrorCode error_code;
    113 
    114   /**
    115    * Response as JSON
    116   */
    117   json_t *response;
    118 
    119   /**
    120    * Pointer to our AuthChallengeRequestOperation
    121   */
    122   struct FROSIX_ChallengeRequestOperation *ao;
    123 };
    124 
    125 
    126 /**
    127  * Function to free all initialized memory of a provider from a
    128  * `struct FROSIX_Provider`
    129  *
    130  * @param fp the struct to clean up
    131 */
    132 static void
    133 free_provider_struct (struct FROSIX_Provider *fp)
    134 {
    135   if (NULL != fp->backend_url)
    136     GNUNET_free (fp->backend_url);
    137 
    138   if (NULL != fp->auth_method)
    139     GNUNET_free (fp->auth_method);
    140 
    141   if (NULL != fp->auth_data)
    142     GNUNET_free (fp->auth_data);
    143 }
    144 
    145 
    146 /**
    147  * Function called when challenge-request process is being aborted.
    148  * Frees all initialized memory!
    149  *
    150  * @param cls a `struct FROSIX_ChallengeRequestState`
    151 */
    152 static void
    153 challenge_request_cancel_cb (void *cls)
    154 {
    155   struct FROSIX_ChallengeRequestState *cs = cls;
    156 
    157   if (NULL != cs->challenge_data)
    158   {
    159     free_provider_struct (&cs->challenge_data->provider);
    160     GNUNET_free (cs->challenge_data);
    161   }
    162 
    163   GNUNET_free (cs);
    164 }
    165 
    166 
    167 /**
    168  * FIXME
    169 */
    170 static void
    171 return_feedback (struct FROSIX_ChallengeRequestState *cs)
    172 {
    173   /* return empty */
    174   cs->cb (cs->cb_cls,
    175           cs->error_code,
    176           cs->response);
    177 }
    178 
    179 
    180 /**
    181  * Callback to process a POST /auth-challenge request
    182  *
    183  * @param cls closure
    184  * @param scd the decoded response body
    185 */
    186 static void
    187 challenge_request_cb (void *cls,
    188                       const struct FROSIX_ChallengeRequestDetails *crd)
    189 {
    190   GNUNET_assert (NULL != cls);
    191   struct FROSIX_ChallengeRequestState *cs = cls;
    192 
    193   /* set error code */
    194   cs->error_code = crd->ec;
    195   cs->response = json_deep_copy (crd->response);
    196 
    197   /* call callback and give a return message to the user */
    198   return_feedback (cs);
    199 }
    200 
    201 
    202 /**
    203  * FIXME
    204 */
    205 static void
    206 start_challenge_request (struct FROSIX_ChallengeRequestState *cs)
    207 {
    208   /* calculate request id*/
    209   struct FROSIX_ChallengeRequestIdP request_id;
    210   FROSIX_compute_challenge_request_id (
    211     &request_id,
    212     &cs->challenge_data->provider.enc_key,
    213     &cs->challenge_data->message_hash);
    214 
    215   cs->ao = FROSIX_auth_challenge_post (
    216     FROSIX_REDUX_ctx_,
    217     cs->challenge_data->provider.backend_url,
    218     &request_id,
    219     &cs->challenge_data->provider.enc_key,
    220     cs->challenge_data->provider.auth_method,
    221     cs->challenge_data->provider.auth_data,
    222     &cs->challenge_data->provider.auth_nonce,
    223     &cs->challenge_data->message_hash,
    224     &challenge_request_cb,
    225     cs);
    226 }
    227 
    228 
    229 /**
    230  * Helper function to parse a keygen input
    231  *
    232  * @param[in,out] dkg_data A initialized struct
    233  * @param[in] arguments Input from the cli
    234 */
    235 enum GNUNET_GenericReturnValue
    236 parse_challenge_request_arguments (
    237   struct FROSIX_ChallengeRequestData *challenge_data,
    238   const json_t *arguments,
    239   const json_t *input)
    240 {
    241   json_t *providers = NULL;
    242 
    243   struct GNUNET_JSON_Specification spec[] = {
    244     GNUNET_JSON_spec_json ("providers",
    245                            &providers),
    246     GNUNET_JSON_spec_end ()
    247   };
    248 
    249   if (GNUNET_OK != GNUNET_JSON_parse (arguments,
    250                                       spec,
    251                                       NULL,
    252                                       NULL))
    253   {
    254     GNUNET_break (0);
    255     GNUNET_JSON_parse_free (spec);
    256     return GNUNET_NO;
    257   }
    258 
    259   /* check number of parsed providers */
    260   size_t max_num = json_array_size (providers);
    261 
    262   /* enforce that only one provider is selected */
    263   GNUNET_assert (1 == json_object_size (input));
    264 
    265   struct GNUNET_JSON_Specification selection_spec[] = {
    266     GNUNET_JSON_spec_uint8 ("provider_index",
    267                             &challenge_data->provider.provider_index),
    268     GNUNET_JSON_spec_end ()
    269   };
    270 
    271   if (GNUNET_OK != GNUNET_JSON_parse (input,
    272                                       selection_spec,
    273                                       NULL,
    274                                       NULL))
    275   {
    276     GNUNET_break (0);
    277     GNUNET_JSON_parse_free (selection_spec);
    278     GNUNET_JSON_parse_free (spec);
    279     return GNUNET_NO;
    280   }
    281 
    282   GNUNET_JSON_parse_free (selection_spec);
    283 
    284   /* check if our selected provider is in the keyfile */
    285   GNUNET_assert (max_num > challenge_data->provider.provider_index);
    286   GNUNET_assert (0 < challenge_data->provider.provider_index);
    287   uint8_t parsed_provider_index;
    288 
    289   /* parse provider data */
    290   struct GNUNET_JSON_Specification prov_spec[] = {
    291     GNUNET_JSON_spec_uint8 ("provider_index",
    292                             &parsed_provider_index),
    293     GNUNET_JSON_spec_string (
    294       "backend_url",
    295       (const char**) &challenge_data->provider.backend_url),
    296     GNUNET_JSON_spec_fixed_auto ("encryption_key",
    297                                  &challenge_data->provider.enc_key),
    298     GNUNET_JSON_spec_string (
    299       "auth_method",
    300       (const char**) &challenge_data->provider.auth_method),
    301     GNUNET_JSON_spec_string (
    302       "auth_data",
    303       (const char**) &challenge_data->provider.auth_data),
    304     GNUNET_JSON_spec_fixed_auto ("auth_nonce",
    305                                  &challenge_data->provider.auth_nonce),
    306     GNUNET_JSON_spec_end ()
    307   };
    308 
    309   if (GNUNET_OK != GNUNET_JSON_parse (
    310         json_array_get (
    311           providers,
    312           challenge_data->provider.provider_index - 1),
    313         prov_spec,
    314         NULL,
    315         NULL))
    316   {
    317     GNUNET_break (0);
    318     GNUNET_JSON_parse_free (prov_spec);
    319     GNUNET_JSON_parse_free (spec);
    320     return GNUNET_NO;
    321   }
    322 
    323   GNUNET_JSON_parse_free (prov_spec);
    324   GNUNET_JSON_parse_free (spec);
    325 
    326   /* check if parsed provider has correct index */
    327   GNUNET_assert (parsed_provider_index ==
    328                  challenge_data->provider.provider_index);
    329 
    330   return GNUNET_OK;
    331 }
    332 
    333 
    334 /**
    335  *
    336 */
    337 struct FROSIX_ReduxAction *
    338 FROSIX_redux_challenge_request_start (const json_t *arguments,
    339                                       const json_t *input,
    340                                       const char *message,
    341                                       FROSIX_ActionCallback cb,
    342                                       void *cb_cls)
    343 {
    344   /* initialize signature data struct */
    345   struct FROSIX_ChallengeRequestData *challenge_data =
    346     GNUNET_new (struct FROSIX_ChallengeRequestData);
    347 
    348   /* parse arguments from cli */
    349   if (GNUNET_OK != parse_challenge_request_arguments (challenge_data,
    350                                                       arguments,
    351                                                       input))
    352   {
    353     // free_challenge_request_data_struct (challenge_data);
    354 
    355     // FIXME: Return some useful error message
    356     return NULL;
    357   }
    358 
    359   /* hash message */
    360   FROST_message_to_hash (&challenge_data->message_hash,
    361                          message,
    362                          strlen (message));
    363 
    364   /* lets create a state */
    365   struct FROSIX_ChallengeRequestState *cs = GNUNET_new (struct
    366                                                         FROSIX_ChallengeRequestState);
    367   cs->cb = cb;
    368   cs->cb_cls = cb_cls;
    369   cs->challenge_data = challenge_data;
    370   cs->ra.cleanup = &challenge_request_cancel_cb;
    371   cs->ra.cleanup_cls = cs;
    372 
    373   /* get commitments from all parsed providers */
    374   start_challenge_request (cs);
    375 
    376   return &cs->ra;
    377 }