testing_cmd_secret_share.c (10699B)
1 /* 2 This file is part of Anastasis 3 Copyright (C) 2020 Anastasis SARL 4 5 Anastasis 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 Anastasis 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 Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/> 15 */ 16 /** 17 * @file testing/testing_cmd_secret_share.c 18 * @brief command to execute the anastasis secret share service 19 * @author Christian Grothoff 20 * @author Dennis Neufeld 21 * @author Dominik Meister 22 */ 23 24 #include "platform.h" 25 struct SecretShareState; 26 #define ANASTASIS_SHARE_RESULT_CLOSURE struct SecretShareState 27 #include "anastasis_testing_lib.h" 28 #include <taler/taler_util.h> 29 #include <taler/taler_testing_lib.h> 30 #include <taler/taler_merchant_service.h> 31 32 33 /** 34 * State for a "secret share" CMD. 35 */ 36 struct SecretShareState 37 { 38 /** 39 * Claim token we got back, if any. Otherwise all zeros. 40 */ 41 struct TALER_ClaimTokenP token; 42 43 /** 44 * The interpreter state. 45 */ 46 struct TALER_TESTING_Interpreter *is; 47 48 /** 49 * Label of this command. 50 */ 51 const char *label; 52 53 /** 54 * References to commands of previous policy creations. 55 */ 56 const char **cmd_label_array; 57 58 /** 59 * Data to derive user identifier from. 60 */ 61 json_t *id_data; 62 63 /** 64 * The core secret to backup/recover. 65 */ 66 const void *core_secret; 67 68 /** 69 * URL of the anastasis backend. 70 */ 71 const char *anastasis_url; 72 73 /** 74 * URL of a /config command for the @e anastasis_url. 75 */ 76 const char *config_ref; 77 78 /** 79 * The /truth GET operation handle. 80 */ 81 struct ANASTASIS_SecretShare *sso; 82 83 /** 84 * Reference to previous secret share command we expect to lookup. 85 */ 86 const char *prev_secret_share; 87 88 /** 89 * closure for the payment callback 90 */ 91 void *spc_cls; 92 93 /** 94 * closure for the result callback 95 */ 96 void *src_cls; 97 98 /** 99 * Payment order ID we got back, if any. Otherwise NULL. 100 */ 101 char *payment_order_id; 102 103 /** 104 * Size of core_secret. 105 */ 106 size_t core_secret_size; 107 108 /** 109 * Length of array of command labels (cmd_label_array). 110 */ 111 unsigned int cmd_label_array_length; 112 113 /** 114 * Expected status code. 115 */ 116 enum ANASTASIS_ShareStatus want_status; 117 118 /** 119 * Options for how we are supposed to do the upload. 120 */ 121 enum ANASTASIS_TESTING_SecretShareOption ssopt; 122 }; 123 124 125 /** 126 * Function called with the results of a #ANASTASIS_secret_share(). 127 * 128 * @param sss closure 129 * @param sr result from the operation 130 */ 131 static void 132 secret_share_result_cb (struct SecretShareState *sss, 133 const struct ANASTASIS_ShareResult *sr) 134 { 135 sss->sso = NULL; 136 if (sr->ss != sss->want_status) 137 { 138 TALER_TESTING_interpreter_fail (sss->is); 139 return; 140 } 141 switch (sr->ss) 142 { 143 case ANASTASIS_SHARE_STATUS_SUCCESS: 144 break; 145 case ANASTASIS_SHARE_STATUS_PAYMENT_REQUIRED: 146 { 147 struct TALER_MERCHANT_PayUriData pd; 148 149 GNUNET_assert (0 < sr->details.payment_required.payment_requests_length); 150 if (GNUNET_OK != 151 TALER_MERCHANT_parse_pay_uri ( 152 sr->details.payment_required.payment_requests[0].payment_request_url 153 , 154 &pd)) 155 { 156 GNUNET_break (0); 157 TALER_TESTING_interpreter_fail (sss->is); 158 return; 159 } 160 sss->payment_order_id = GNUNET_strdup (pd.order_id); 161 TALER_MERCHANT_parse_pay_uri_free (&pd); 162 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 163 "Order ID from Anastasis service is `%s'\n", 164 sss->payment_order_id); 165 } 166 break; 167 case ANASTASIS_SHARE_STATUS_PROVIDER_FAILED: 168 break; 169 } 170 TALER_TESTING_interpreter_next (sss->is); 171 } 172 173 174 /** 175 * Run a "secret share" CMD. 176 * 177 * @param cls closure. 178 * @param cmd command currently being run. 179 * @param is interpreter state. 180 */ 181 static void 182 secret_share_run (void *cls, 183 const struct TALER_TESTING_Command *cmd, 184 struct TALER_TESTING_Interpreter *is) 185 { 186 struct SecretShareState *sss = cls; 187 const struct ANASTASIS_Policy *policies[sss->cmd_label_array_length]; 188 struct ANASTASIS_ProviderDetails pds; 189 190 GNUNET_assert (sss->cmd_label_array_length > 0); 191 GNUNET_assert (NULL != sss->cmd_label_array); 192 sss->is = is; 193 if (NULL != sss->cmd_label_array) 194 { 195 for (unsigned int i = 0; i < sss->cmd_label_array_length; i++) 196 { 197 const struct TALER_TESTING_Command *ref; 198 const struct ANASTASIS_Policy **policy; 199 200 ref = TALER_TESTING_interpreter_lookup_command (is, 201 sss->cmd_label_array[i]); 202 if (NULL == ref) 203 { 204 GNUNET_break (0); 205 TALER_TESTING_interpreter_fail (sss->is); 206 return; 207 } 208 if (GNUNET_OK != 209 ANASTASIS_TESTING_get_trait_policy (ref, 210 &policy)) 211 { 212 GNUNET_break (0); 213 TALER_TESTING_interpreter_fail (sss->is); 214 return; 215 } 216 GNUNET_assert (NULL != *policy); 217 policies[i] = *policy; 218 } 219 } 220 221 if (NULL != sss->prev_secret_share) 222 { 223 const struct TALER_TESTING_Command *ref; 224 const char *order_id; 225 226 ref = TALER_TESTING_interpreter_lookup_command (is, 227 sss->prev_secret_share); 228 if (NULL == ref) 229 { 230 GNUNET_break (0); 231 TALER_TESTING_interpreter_fail (sss->is); 232 return; 233 } 234 if (GNUNET_OK != 235 TALER_TESTING_get_trait_order_id (ref, 236 &order_id)) 237 { 238 GNUNET_break (0); 239 TALER_TESTING_interpreter_fail (sss->is); 240 return; 241 } 242 sss->payment_order_id = GNUNET_strdup (order_id); 243 if (NULL == sss->payment_order_id) 244 { 245 GNUNET_break (0); 246 TALER_TESTING_interpreter_fail (sss->is); 247 return; 248 } 249 } 250 251 memset (&pds, 252 0, 253 sizeof (pds)); 254 if (NULL != sss->payment_order_id) 255 { 256 if (GNUNET_OK != 257 GNUNET_STRINGS_string_to_data ( 258 sss->payment_order_id, 259 strlen (sss->payment_order_id), 260 &pds.payment_secret, 261 sizeof (struct ANASTASIS_PaymentSecretP))) 262 { 263 GNUNET_break (0); 264 TALER_TESTING_interpreter_fail (sss->is); 265 GNUNET_free (sss->payment_order_id); 266 return; 267 } 268 GNUNET_free (sss->payment_order_id); 269 } 270 pds.provider_url = sss->anastasis_url; 271 { 272 const struct TALER_TESTING_Command *ref; 273 const struct ANASTASIS_CRYPTO_ProviderSaltP *provider_salt; 274 275 ref = TALER_TESTING_interpreter_lookup_command (is, 276 sss->config_ref); 277 if (NULL == ref) 278 { 279 GNUNET_break (0); 280 TALER_TESTING_interpreter_fail (sss->is); 281 return; 282 } 283 if (GNUNET_OK != 284 ANASTASIS_TESTING_get_trait_provider_salt (ref, 285 &provider_salt)) 286 { 287 GNUNET_break (0); 288 TALER_TESTING_interpreter_fail (sss->is); 289 return; 290 } 291 pds.provider_salt = *provider_salt; 292 } 293 294 sss->sso = ANASTASIS_secret_share ( 295 TALER_TESTING_interpreter_get_context (is), 296 sss->id_data, 297 &pds, 298 1, 299 policies, 300 sss->cmd_label_array_length, 301 false, 302 GNUNET_TIME_UNIT_ZERO, 303 &secret_share_result_cb, 304 sss, 305 "test-case", 306 sss->core_secret, 307 sss->core_secret_size); 308 if (NULL == sss->sso) 309 { 310 GNUNET_break (0); 311 TALER_TESTING_interpreter_fail (sss->is); 312 return; 313 } 314 } 315 316 317 /** 318 * Free the state of a "secret share" CMD, and possibly 319 * cancel it if it did not complete. 320 * 321 * @param cls closure. 322 * @param cmd command being freed. 323 */ 324 static void 325 secret_share_cleanup (void *cls, 326 const struct TALER_TESTING_Command *cmd) 327 { 328 struct SecretShareState *sss = cls; 329 330 if (NULL != sss->cmd_label_array) 331 { 332 GNUNET_free (sss->cmd_label_array); 333 } 334 if (NULL != sss->sso) 335 { 336 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 337 "Command '%s' did not complete\n", 338 cmd->label); 339 ANASTASIS_secret_share_cancel (sss->sso); 340 sss->sso = NULL; 341 } 342 json_decref (sss->id_data); 343 GNUNET_free (sss); 344 } 345 346 347 /** 348 * Offer internal data to other commands. 349 * 350 * @param cls closure 351 * @param[out] ret result (could be anything) 352 * @param trait name of the trait 353 * @param index index number of the object to extract. 354 * @return #GNUNET_OK on success 355 */ 356 static int 357 secret_share_traits (void *cls, 358 const void **ret, 359 const char *trait, 360 unsigned int index) 361 { 362 struct SecretShareState *sss = cls; 363 struct TALER_TESTING_Trait traits[] = { 364 TALER_TESTING_make_trait_claim_token (&sss->token), 365 ANASTASIS_TESTING_make_trait_core_secret (sss->core_secret), 366 TALER_TESTING_make_trait_order_id (sss->payment_order_id), 367 TALER_TESTING_trait_end () 368 }; 369 370 return TALER_TESTING_get_trait (traits, 371 ret, 372 trait, 373 index); 374 } 375 376 377 struct TALER_TESTING_Command 378 ANASTASIS_TESTING_cmd_secret_share ( 379 const char *label, 380 const char *anastasis_url, 381 const char *config_ref, 382 const char *prev_secret_share, 383 const json_t *id_data, 384 const void *core_secret, 385 size_t core_secret_size, 386 enum ANASTASIS_ShareStatus want_status, 387 enum ANASTASIS_TESTING_SecretShareOption sso, 388 ...) 389 { 390 struct SecretShareState *sss; 391 392 sss = GNUNET_new (struct SecretShareState); 393 sss->want_status = want_status; 394 sss->ssopt = sso; 395 sss->anastasis_url = anastasis_url; 396 sss->config_ref = config_ref; 397 sss->label = label; 398 sss->id_data = json_incref ((json_t *) id_data); 399 sss->core_secret = core_secret; 400 sss->core_secret_size = core_secret_size; 401 sss->prev_secret_share = prev_secret_share; 402 403 { 404 const char *policy_create_cmd; 405 va_list ap; 406 407 va_start (ap, 408 sso); 409 while (NULL != (policy_create_cmd = va_arg (ap, const char *))) 410 { 411 GNUNET_array_append (sss->cmd_label_array, 412 sss->cmd_label_array_length, 413 policy_create_cmd); 414 } 415 va_end (ap); 416 } 417 { 418 struct TALER_TESTING_Command cmd = { 419 .cls = sss, 420 .label = label, 421 .run = &secret_share_run, 422 .cleanup = &secret_share_cleanup, 423 .traits = &secret_share_traits 424 }; 425 426 return cmd; 427 } 428 } 429 430 431 /* end of testing_cmd_secret_share.c */