frosix

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

frosix_api.c (9288B)


      1 /*
      2   This file is part of Frosix
      3   Copyright (C) 2020, 2021, 2022 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 libfrosix/frosix_api.c
     18  * @brief frosix client api
     19  * @author Christian Grothoff
     20  * @author Dominik Meister
     21  * @author Dennis Neufeld
     22  */
     23 #include <platform.h>
     24 #include <jansson.h>
     25 #include "frosix.h"
     26 // #include "anastasis_error_codes.h"
     27 #include <taler/taler_json_lib.h>
     28 #include "frosix_api.h"
     29 #include "frost_verify.h"
     30 #include "frost_high.h"
     31 #include "frost_low.h"
     32 #include "frost_high.h"
     33 
     34 
     35 /**
     36  * Reducer API's CURL context handle.
     37  */
     38 struct GNUNET_CURL_Context *FROSIX_REDUX_ctx_;
     39 
     40 void
     41 FROSIX_redux_fail_ (FROSIX_ActionCallback cb,
     42                     void *cb_cls,
     43                     enum TALER_ErrorCode ec,
     44                     const char *detail)
     45 {
     46   json_t *estate;
     47 
     48   estate = GNUNET_JSON_PACK (
     49     GNUNET_JSON_pack_allow_null (
     50       GNUNET_JSON_pack_string ("detail",
     51                                detail)),
     52     GNUNET_JSON_pack_string ("reducer_type",
     53                              "error"),
     54     GNUNET_JSON_pack_uint64 ("code",
     55                              ec),
     56     GNUNET_JSON_pack_string ("hint",
     57                              TALER_ErrorCode_get_hint (ec)));
     58   cb (cb_cls,
     59       ec,
     60       estate);
     61   json_decref (estate);
     62 }
     63 
     64 
     65 void
     66 FROSIX_redux_init (struct GNUNET_CURL_Context *ctx)
     67 {
     68   FROSIX_REDUX_ctx_ = ctx;
     69 }
     70 
     71 
     72 void
     73 FROSIX_redux_action_cancel (struct FROSIX_ReduxAction *ra)
     74 {
     75   ra->cleanup (ra->cleanup_cls);
     76 }
     77 
     78 
     79 enum GNUNET_GenericReturnValue
     80 FROSIX_verify_signature (const char *message,
     81                          const json_t *arguments)
     82 {
     83   /* parse json */
     84   struct FROST_MessageHash mh;
     85   struct FROST_PublicKey pk;
     86   struct FROST_Signature sig;
     87 
     88   struct GNUNET_JSON_Specification spec[] = {
     89     GNUNET_JSON_spec_fixed_auto ("message_hash",
     90                                  &mh),
     91     GNUNET_JSON_spec_fixed_auto ("public_key",
     92                                  &pk),
     93     GNUNET_JSON_spec_fixed_auto ("signature_r",
     94                                  &sig.r),
     95     GNUNET_JSON_spec_fixed_auto ("signature_z",
     96                                  &sig.z),
     97     GNUNET_JSON_spec_end ()
     98   };
     99 
    100   if (GNUNET_OK != GNUNET_JSON_parse (arguments,
    101                                       spec,
    102                                       NULL,
    103                                       NULL))
    104   {
    105     GNUNET_break (0);
    106     GNUNET_JSON_parse_free (spec);
    107     return GNUNET_NO;
    108   }
    109 
    110   /* check if hash of message matches hash in signature */
    111   struct FROST_MessageHash input_mh;
    112   FROST_message_to_hash (&input_mh,
    113                          message,
    114                          strlen (message));
    115 
    116   if (GNUNET_OK != FROST_hash_cmp (&mh.hash,
    117                                    &input_mh.hash))
    118     return GNUNET_NO;
    119 
    120   return FROST_verify_signature (&pk,
    121                                  &sig,
    122                                  &mh);
    123 }
    124 
    125 
    126 void
    127 FROSIX_export_public_key (const json_t *arguments,
    128                           FROSIX_ActionCallback cb,
    129                           void *cb_cls)
    130 {
    131   json_t *result = json_object ();
    132 
    133   /* public key*/
    134   json_object_set (result,
    135                    "public_key",
    136                    json_object_get (arguments,
    137                                     "public_key"));
    138 
    139   /* provider array */
    140   json_t *providers = json_object_get (arguments,
    141                                        "providers");
    142   size_t num_of_providers = json_array_size (providers);
    143 
    144   /* go through each provider */
    145   json_t *temp_providers = json_array ();
    146   for (size_t i = 0; i < num_of_providers; i++)
    147   {
    148     json_t *provider_i = json_array_get (providers,
    149                                          i);
    150 
    151     json_t *temp_provider = json_object ();
    152 
    153     json_object_set (temp_provider,
    154                      "provider_name",
    155                      json_object_get (provider_i,
    156                                       "provider_name"));
    157 
    158     json_object_set (temp_provider,
    159                      "backend_url",
    160                      json_object_get (provider_i,
    161                                       "backend_url"));
    162 
    163     /* parse authentication data and compute salted hash */
    164     {
    165       struct FROSIX_ChallengeHashP auth_hash;
    166       /*const char *auth_method = NULL;
    167       const char *auth_data = NULL;
    168       const char *auth_answer = NULL;
    169       struct GNUNET_HashCode auth_nonce;
    170 
    171       struct GNUNET_JSON_Specification spec[] = {
    172         GNUNET_JSON_spec_string ("auth_method",
    173                                  &auth_method),
    174         GNUNET_JSON_spec_string ("auth_data",
    175                                  &auth_data),
    176         GNUNET_JSON_spec_fixed_auto ("auth_nonce",
    177                                      &auth_nonce),
    178         GNUNET_JSON_spec_mark_optional (
    179         GNUNET_JSON_spec_string ("auth_answer",
    180                                  &auth_answer),
    181                                  NULL),
    182         GNUNET_JSON_spec_end ()
    183       };*/
    184 
    185       struct GNUNET_JSON_Specification spec[] = {
    186         GNUNET_JSON_spec_fixed_auto ("auth_hash",
    187                                      &auth_hash),
    188         GNUNET_JSON_spec_end ()
    189       };
    190 
    191       if (GNUNET_OK != GNUNET_JSON_parse (provider_i,
    192                                           spec,
    193                                           NULL,
    194                                           NULL))
    195       {
    196         GNUNET_break (0);
    197         GNUNET_JSON_parse_free (spec);
    198         return;
    199       }
    200 
    201       /*FROSIX_compute_auth_hash (&auth_hash,
    202                                       auth_data,
    203                                       &auth_nonce);*/
    204 
    205       json_t *j_hash;
    206       j_hash = GNUNET_JSON_PACK (
    207         GNUNET_JSON_pack_data_auto ("auth_hash",
    208                                     &auth_hash));
    209 
    210       json_object_update_new (temp_provider,
    211                               j_hash);
    212 
    213       GNUNET_JSON_parse_free (spec);
    214     }
    215 
    216 
    217     json_object_set (temp_provider,
    218                      "provider_signature",
    219                      json_object_get (provider_i,
    220                                       "provider_signature"));
    221 
    222     json_object_set (temp_provider,
    223                      "provider_public_key",
    224                      json_object_get (provider_i,
    225                                       "provider_public_key"));
    226 
    227     json_array_append_new (temp_providers,
    228                            temp_provider);
    229   }
    230 
    231   json_object_set_new (result,
    232                        "providers",
    233                        temp_providers);
    234 
    235   enum TALER_ErrorCode error_code = TALER_EC_NONE;
    236   cb (cb_cls,
    237       error_code,
    238       result);
    239 }
    240 
    241 
    242 enum GNUNET_GenericReturnValue
    243 FROSIX_verify_public_key (const json_t *arguments)
    244 {
    245   struct FROST_PublicKey pk;
    246   json_t *providers;
    247 
    248   struct GNUNET_JSON_Specification spec[] = {
    249     GNUNET_JSON_spec_fixed_auto ("public_key",
    250                                  &pk),
    251     GNUNET_JSON_spec_json ("providers",
    252                            &providers),
    253     GNUNET_JSON_spec_end ()
    254   };
    255 
    256   if (GNUNET_OK != GNUNET_JSON_parse (arguments,
    257                                       spec,
    258                                       NULL,
    259                                       NULL))
    260   {
    261     GNUNET_break (0);
    262     GNUNET_JSON_parse_free (spec);
    263     return GNUNET_NO;
    264   }
    265 
    266   unsigned int len = json_array_size (providers);
    267 
    268   for (unsigned int i = 0; i < len; i++)
    269   {
    270     struct FROSIX_ChallengeHashP ch;
    271     struct GNUNET_CRYPTO_EddsaSignature sig;
    272     struct GNUNET_CRYPTO_EddsaPublicKey provider_pk;
    273 
    274     struct GNUNET_JSON_Specification provider_spec[] = {
    275       GNUNET_JSON_spec_fixed_auto ("auth_hash",
    276                                    &ch),
    277       GNUNET_JSON_spec_fixed_auto ("provider_signature",
    278                                    &sig),
    279       GNUNET_JSON_spec_fixed_auto ("provider_public_key",
    280                                    &provider_pk),
    281       GNUNET_JSON_spec_end ()
    282     };
    283 
    284     if (GNUNET_OK != GNUNET_JSON_parse (json_array_get (providers,
    285                                                         i),
    286                                         provider_spec,
    287                                         NULL,
    288                                         NULL))
    289     {
    290       GNUNET_break (0);
    291       GNUNET_JSON_parse_free (provider_spec);
    292       GNUNET_JSON_parse_free (spec);
    293       return GNUNET_NO;
    294     }
    295 
    296     struct FROSIX_DkgKeySignaturePS ks = {
    297       .purpose.purpose = htonl (104),
    298       .purpose.size = htonl (sizeof (ks)),
    299       .public_key = pk,
    300       .auth_hash = ch,
    301     };
    302 
    303     if (GNUNET_OK != GNUNET_CRYPTO_eddsa_verify (
    304           104,
    305           &ks,
    306           &sig,
    307           &provider_pk))
    308     {
    309       GNUNET_JSON_parse_free (provider_spec);
    310       GNUNET_JSON_parse_free (spec);
    311       return GNUNET_NO;
    312     }
    313 
    314     GNUNET_JSON_parse_free (provider_spec);
    315   }
    316 
    317   GNUNET_JSON_parse_free (spec);
    318   return GNUNET_OK;
    319 }