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 }