anastasis_backup.c (29351B)
1 /* 2 This file is part of Anastasis 3 Copyright (C) 2020, 2021 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 * @brief anastasis client api 18 * @author Christian Grothoff 19 * @author Dominik Meister 20 * @author Dennis Neufeld 21 */ 22 #include "platform.h" 23 #include "anastasis.h" 24 #include <taler/taler_merchant_service.h> 25 #include <zlib.h> 26 27 28 struct ANASTASIS_Truth 29 { 30 /** 31 * Identification of the truth. 32 */ 33 struct ANASTASIS_CRYPTO_TruthUUIDP uuid; 34 35 /** 36 * Keyshare of this truth, used to generate policy keys 37 */ 38 struct ANASTASIS_CRYPTO_KeyShareP key_share; 39 40 /** 41 * Nonce used for the symmetric encryption. 42 */ 43 struct ANASTASIS_CRYPTO_NonceP nonce; 44 45 /** 46 * Key used to encrypt this truth 47 */ 48 struct ANASTASIS_CRYPTO_TruthKeyP truth_key; 49 50 /** 51 * Server salt used to derive user identifier 52 */ 53 struct ANASTASIS_CRYPTO_ProviderSaltP provider_salt; 54 55 /** 56 * Server salt used to derive hash from security answer 57 */ 58 struct ANASTASIS_CRYPTO_QuestionSaltP question_salt; 59 60 /** 61 * Url of the server 62 */ 63 char *url; 64 65 /** 66 * Method used for this truth 67 */ 68 char *type; 69 70 /** 71 * Instructions for the user to recover this truth. 72 */ 73 char *instructions; 74 75 /** 76 * Mime type of the truth, NULL if not given. 77 */ 78 char *mime_type; 79 80 }; 81 82 83 struct ANASTASIS_Truth * 84 ANASTASIS_truth_from_json (const json_t *json) 85 { 86 struct ANASTASIS_Truth *t = GNUNET_new (struct ANASTASIS_Truth); 87 const char *url; 88 const char *type; 89 const char *instructions; 90 const char *mime_type = NULL; 91 struct GNUNET_JSON_Specification spec[] = { 92 GNUNET_JSON_spec_string ("url", 93 &url), 94 GNUNET_JSON_spec_string ("type", 95 &type), 96 GNUNET_JSON_spec_string ("instructions", 97 &instructions), 98 GNUNET_JSON_spec_mark_optional ( 99 GNUNET_JSON_spec_string ("mime_type", 100 &mime_type), 101 NULL), 102 GNUNET_JSON_spec_fixed_auto ("uuid", 103 &t->uuid), 104 GNUNET_JSON_spec_fixed_auto ("nonce", 105 &t->nonce), 106 GNUNET_JSON_spec_fixed_auto ("key_share", 107 &t->key_share), 108 GNUNET_JSON_spec_fixed_auto ("truth_key", 109 &t->truth_key), 110 GNUNET_JSON_spec_fixed_auto ("question_salt", 111 &t->question_salt), 112 GNUNET_JSON_spec_fixed_auto ("provider_salt", 113 &t->provider_salt), 114 GNUNET_JSON_spec_end () 115 }; 116 117 if (GNUNET_OK != 118 GNUNET_JSON_parse (json, 119 spec, 120 NULL, NULL)) 121 { 122 GNUNET_break_op (0); 123 GNUNET_free (t); 124 return NULL; 125 } 126 t->url = GNUNET_strdup (url); 127 t->type = GNUNET_strdup (type); 128 t->instructions = GNUNET_strdup (instructions); 129 if (NULL != mime_type) 130 t->mime_type = GNUNET_strdup (mime_type); 131 return t; 132 } 133 134 135 json_t * 136 ANASTASIS_truth_to_json (const struct ANASTASIS_Truth *t) 137 { 138 return GNUNET_JSON_PACK ( 139 GNUNET_JSON_pack_data_auto ("uuid", 140 &t->uuid), 141 GNUNET_JSON_pack_data_auto ("key_share", 142 &t->key_share), 143 GNUNET_JSON_pack_data_auto ("truth_key", 144 &t->truth_key), 145 GNUNET_JSON_pack_data_auto ("question_salt", 146 &t->question_salt), 147 GNUNET_JSON_pack_data_auto ("nonce", 148 &t->nonce), 149 GNUNET_JSON_pack_data_auto ("provider_salt", 150 &t->provider_salt), 151 GNUNET_JSON_pack_string ("url", 152 t->url), 153 GNUNET_JSON_pack_string ("type", 154 t->type), 155 GNUNET_JSON_pack_string ("instructions", 156 t->instructions), 157 GNUNET_JSON_pack_allow_null ( 158 GNUNET_JSON_pack_string ("mime_type", 159 t->mime_type))); 160 } 161 162 163 struct ANASTASIS_TruthUpload 164 { 165 166 /** 167 * User identifier used for the keyshare encryption 168 */ 169 struct ANASTASIS_CRYPTO_UserIdentifierP id; 170 171 /** 172 * CURL Context for the Post Request 173 */ 174 struct GNUNET_CURL_Context *ctx; 175 176 /** 177 * Callback which sends back the generated truth object later used to build the policy 178 */ 179 ANASTASIS_TruthCallback tc; 180 181 /** 182 * Closure for the Callback 183 */ 184 void *tc_cls; 185 186 /** 187 * Reference to the Truthstore Operation 188 */ 189 struct ANASTASIS_TruthStoreOperation *tso; 190 191 /** 192 * The truth we are uploading. 193 */ 194 struct ANASTASIS_Truth *t; 195 196 }; 197 198 199 /** 200 * Function called with the result of trying to upload truth. 201 * 202 * @param cls our `struct ANASTASIS_TruthUpload` 203 * @param ud details about the upload result 204 */ 205 static void 206 truth_store_callback (void *cls, 207 const struct ANASTASIS_UploadDetails *ud) 208 { 209 struct ANASTASIS_TruthUpload *tu = cls; 210 211 tu->tso = NULL; 212 tu->tc (tu->tc_cls, 213 tu->t, 214 ud); 215 tu->t = NULL; 216 ANASTASIS_truth_upload_cancel (tu); 217 } 218 219 220 struct ANASTASIS_TruthUpload * 221 ANASTASIS_truth_upload3 (struct GNUNET_CURL_Context *ctx, 222 const struct ANASTASIS_CRYPTO_UserIdentifierP *user_id, 223 struct ANASTASIS_Truth *t, 224 const void *truth_data, 225 size_t truth_data_size, 226 uint32_t payment_years_requested, 227 struct GNUNET_TIME_Relative pay_timeout, 228 ANASTASIS_TruthCallback tc, 229 void *tc_cls) 230 { 231 struct ANASTASIS_TruthUpload *tu; 232 struct ANASTASIS_CRYPTO_EncryptedKeyShareP encrypted_key_share; 233 struct GNUNET_HashCode nt; 234 void *encrypted_truth; 235 size_t encrypted_truth_size; 236 237 tu = GNUNET_new (struct ANASTASIS_TruthUpload); 238 tu->tc = tc; 239 tu->tc_cls = tc_cls; 240 tu->ctx = ctx; 241 tu->id = *user_id; 242 tu->tc = tc; 243 tu->tc_cls = tc_cls; 244 tu->t = t; 245 246 if (0 == strcmp ("question", 247 t->type)) 248 { 249 char *answer; 250 251 answer = GNUNET_strndup (truth_data, 252 truth_data_size); 253 ANASTASIS_CRYPTO_secure_answer_hash (answer, 254 &t->uuid, 255 &t->question_salt, 256 &nt); 257 ANASTASIS_CRYPTO_keyshare_encrypt (&t->key_share, 258 &tu->id, 259 answer, 260 &encrypted_key_share); 261 GNUNET_free (answer); 262 truth_data = &nt; 263 truth_data_size = sizeof (nt); 264 } 265 else 266 { 267 ANASTASIS_CRYPTO_keyshare_encrypt (&t->key_share, 268 &tu->id, 269 NULL, 270 &encrypted_key_share); 271 } 272 ANASTASIS_CRYPTO_truth_encrypt (&t->nonce, 273 &t->truth_key, 274 truth_data, 275 truth_data_size, 276 &encrypted_truth, 277 &encrypted_truth_size); 278 tu->tso = ANASTASIS_truth_store (tu->ctx, 279 t->url, 280 &t->uuid, 281 t->type, 282 &encrypted_key_share, 283 t->mime_type, 284 encrypted_truth_size, 285 encrypted_truth, 286 payment_years_requested, 287 pay_timeout, 288 &truth_store_callback, 289 tu); 290 GNUNET_free (encrypted_truth); 291 if (NULL == tu->tso) 292 { 293 GNUNET_break (0); 294 ANASTASIS_truth_free (t); 295 ANASTASIS_truth_upload_cancel (tu); 296 return NULL; 297 } 298 return tu; 299 } 300 301 302 struct ANASTASIS_TruthUpload * 303 ANASTASIS_truth_upload2 ( 304 struct GNUNET_CURL_Context *ctx, 305 const struct ANASTASIS_CRYPTO_UserIdentifierP *user_id, 306 const char *provider_url, 307 const char *type, 308 const char *instructions, 309 const char *mime_type, 310 const struct ANASTASIS_CRYPTO_ProviderSaltP *provider_salt, 311 const void *truth_data, 312 size_t truth_data_size, 313 uint32_t payment_years_requested, 314 struct GNUNET_TIME_Relative pay_timeout, 315 const struct ANASTASIS_CRYPTO_NonceP *nonce, 316 const struct ANASTASIS_CRYPTO_TruthUUIDP *uuid, 317 const struct ANASTASIS_CRYPTO_QuestionSaltP *question_salt, 318 const struct ANASTASIS_CRYPTO_TruthKeyP *truth_key, 319 const struct ANASTASIS_CRYPTO_KeyShareP *key_share, 320 ANASTASIS_TruthCallback tc, 321 void *tc_cls) 322 { 323 struct ANASTASIS_Truth *t; 324 325 t = GNUNET_new (struct ANASTASIS_Truth); 326 t->url = GNUNET_strdup (provider_url); 327 t->type = GNUNET_strdup (type); 328 t->instructions = (NULL != instructions) 329 ? GNUNET_strdup (instructions) 330 : NULL; 331 t->mime_type = (NULL != mime_type) 332 ? GNUNET_strdup (mime_type) 333 : NULL; 334 t->provider_salt = *provider_salt; 335 t->question_salt = *question_salt; 336 t->nonce = *nonce; 337 t->uuid = *uuid; 338 t->truth_key = *truth_key; 339 t->key_share = *key_share; 340 return ANASTASIS_truth_upload3 (ctx, 341 user_id, 342 t, 343 truth_data, 344 truth_data_size, 345 payment_years_requested, 346 pay_timeout, 347 tc, 348 tc_cls); 349 } 350 351 352 struct ANASTASIS_TruthUpload * 353 ANASTASIS_truth_upload ( 354 struct GNUNET_CURL_Context *ctx, 355 const struct ANASTASIS_CRYPTO_UserIdentifierP *user_id, 356 const char *provider_url, 357 const char *type, 358 const char *instructions, 359 const char *mime_type, 360 const struct ANASTASIS_CRYPTO_ProviderSaltP *provider_salt, 361 const void *truth_data, 362 size_t truth_data_size, 363 uint32_t payment_years_requested, 364 struct GNUNET_TIME_Relative pay_timeout, 365 ANASTASIS_TruthCallback tc, 366 void *tc_cls) 367 { 368 struct ANASTASIS_CRYPTO_QuestionSaltP question_salt; 369 struct ANASTASIS_CRYPTO_TruthUUIDP uuid; 370 struct ANASTASIS_CRYPTO_TruthKeyP truth_key; 371 struct ANASTASIS_CRYPTO_KeyShareP key_share; 372 struct ANASTASIS_CRYPTO_NonceP nonce; 373 374 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, 375 &nonce, 376 sizeof (nonce)); 377 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, 378 &question_salt, 379 sizeof (question_salt)); 380 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, 381 &uuid, 382 sizeof (uuid)); 383 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG, 384 &truth_key, 385 sizeof (truth_key)); 386 ANASTASIS_CRYPTO_keyshare_create (&key_share); 387 return ANASTASIS_truth_upload2 (ctx, 388 user_id, 389 provider_url, 390 type, 391 instructions, 392 mime_type, 393 provider_salt, 394 truth_data, 395 truth_data_size, 396 payment_years_requested, 397 pay_timeout, 398 &nonce, 399 &uuid, 400 &question_salt, 401 &truth_key, 402 &key_share, 403 tc, 404 tc_cls); 405 } 406 407 408 void 409 ANASTASIS_truth_upload_cancel (struct ANASTASIS_TruthUpload *tu) 410 { 411 if (NULL != tu->tso) 412 { 413 ANASTASIS_truth_store_cancel (tu->tso); 414 tu->tso = NULL; 415 } 416 if (NULL != tu->t) 417 { 418 ANASTASIS_truth_free (tu->t); 419 tu->t = NULL; 420 } 421 GNUNET_free (tu); 422 } 423 424 425 void 426 ANASTASIS_truth_free (struct ANASTASIS_Truth *t) 427 { 428 GNUNET_free (t->url); 429 GNUNET_free (t->type); 430 GNUNET_free (t->instructions); 431 GNUNET_free (t->mime_type); 432 GNUNET_free (t); 433 } 434 435 436 struct ANASTASIS_Policy 437 { 438 /** 439 * Encrypted policy master key 440 */ 441 struct ANASTASIS_CRYPTO_PolicyKeyP policy_key; 442 443 /** 444 * Salt used to encrypt the master key 445 */ 446 struct ANASTASIS_CRYPTO_MasterSaltP master_salt; 447 448 /** 449 * Array of truths 450 */ 451 struct ANASTASIS_Truth **truths; 452 453 /** 454 * Length of @ truths array. 455 */ 456 uint32_t truths_length; 457 458 }; 459 460 461 /** 462 * Duplicate truth object. 463 * 464 * @param t object to duplicate 465 * @return copy of @a t 466 */ 467 static struct ANASTASIS_Truth * 468 truth_dup (const struct ANASTASIS_Truth *t) 469 { 470 struct ANASTASIS_Truth *d = GNUNET_new (struct ANASTASIS_Truth); 471 472 *d = *t; 473 d->url = GNUNET_strdup (t->url); 474 d->type = GNUNET_strdup (t->type); 475 d->instructions = GNUNET_strdup (t->instructions); 476 if (NULL != t->mime_type) 477 d->mime_type = GNUNET_strdup (t->mime_type); 478 return d; 479 } 480 481 482 struct ANASTASIS_Policy * 483 ANASTASIS_policy_create (const struct ANASTASIS_Truth *truths[], 484 unsigned int truths_len) 485 { 486 struct ANASTASIS_Policy *p; 487 488 p = GNUNET_new (struct ANASTASIS_Policy); 489 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, 490 &p->master_salt, 491 sizeof (p->master_salt)); 492 { 493 struct ANASTASIS_CRYPTO_KeyShareP key_shares[truths_len]; 494 495 for (unsigned int i = 0; i < truths_len; i++) 496 key_shares[i] = truths[i]->key_share; 497 ANASTASIS_CRYPTO_policy_key_derive (key_shares, 498 truths_len, 499 &p->master_salt, 500 &p->policy_key); 501 } 502 p->truths = GNUNET_new_array (truths_len, 503 struct ANASTASIS_Truth *); 504 for (unsigned int i = 0; i<truths_len; i++) 505 p->truths[i] = truth_dup (truths[i]); 506 p->truths_length = truths_len; 507 return p; 508 } 509 510 511 void 512 ANASTASIS_policy_destroy (struct ANASTASIS_Policy *p) 513 { 514 for (unsigned int i = 0; i<p->truths_length; i++) 515 ANASTASIS_truth_free (p->truths[i]); 516 GNUNET_free (p->truths); 517 GNUNET_free (p); 518 } 519 520 521 /** 522 * State for a "policy store" CMD. 523 */ 524 struct PolicyStoreState 525 { 526 /** 527 * User identifier used as entropy source for the account public key 528 */ 529 struct ANASTASIS_CRYPTO_UserIdentifierP id; 530 531 /** 532 * Hash of the current upload. Used to check the server's response. 533 */ 534 struct GNUNET_HashCode curr_hash; 535 536 /** 537 * Payment identifier. 538 */ 539 struct ANASTASIS_PaymentSecretP payment_secret; 540 541 /** 542 * Server salt. Points into a truth object from which we got the 543 * salt. 544 */ 545 struct ANASTASIS_CRYPTO_ProviderSaltP provider_salt; 546 547 /** 548 * The /policy POST operation handle. 549 */ 550 struct ANASTASIS_PolicyStoreOperation *pso; 551 552 /** 553 * URL of the anastasis backend. 554 */ 555 char *anastasis_url; 556 557 /** 558 * Payment request returned by this provider, if any. 559 */ 560 char *payment_request; 561 562 /** 563 * reference to SecretShare 564 */ 565 struct ANASTASIS_SecretShare *ss; 566 567 /** 568 * Version of the policy created at the provider. 569 */ 570 unsigned long long policy_version; 571 572 /** 573 * When will the policy expire at the provider. 574 */ 575 struct GNUNET_TIME_Timestamp policy_expiration; 576 577 }; 578 579 /** 580 * Defines a recovery document upload process (recovery document consists of multiple policies) 581 */ 582 struct ANASTASIS_SecretShare 583 { 584 /** 585 * Closure for the Result Callback 586 */ 587 struct GNUNET_CURL_Context *ctx; 588 589 /** 590 * Callback which gives back the result of the POST Request 591 */ 592 ANASTASIS_ShareResultCallback src; 593 594 /** 595 * Closure for the Result Callback 596 */ 597 void *src_cls; 598 599 /** 600 * References for the upload states and operations (size of truths passed) 601 */ 602 struct PolicyStoreState *pss; 603 604 /** 605 * Closure for the Result Callback 606 */ 607 unsigned int pss_length; 608 }; 609 610 611 /** 612 * Callback to process a POST /policy request 613 * 614 * @param cls closure 615 * @param ud the decoded response body 616 */ 617 static void 618 policy_store_cb (void *cls, 619 const struct ANASTASIS_UploadDetails *ud) 620 { 621 struct PolicyStoreState *pss = cls; 622 struct ANASTASIS_SecretShare *ss = pss->ss; 623 enum ANASTASIS_UploadStatus us; 624 625 pss->pso = NULL; 626 us = ud->us; 627 if ( (ANASTASIS_US_SUCCESS == us) && 628 (0 != GNUNET_memcmp (&pss->curr_hash, 629 ud->details.success.curr_backup_hash)) ) 630 { 631 GNUNET_break_op (0); 632 us = ANASTASIS_US_SERVER_ERROR; 633 } 634 switch (us) 635 { 636 case ANASTASIS_US_SUCCESS: 637 pss->policy_version = ud->details.success.policy_version; 638 pss->policy_expiration = ud->details.success.policy_expiration; 639 break; 640 case ANASTASIS_US_PAYMENT_REQUIRED: 641 pss->payment_request = GNUNET_strdup (ud->details.payment.payment_request); 642 pss->payment_secret = ud->details.payment.ps; 643 break; 644 case ANASTASIS_US_HTTP_ERROR: 645 case ANASTASIS_US_CLIENT_ERROR: 646 case ANASTASIS_US_SERVER_ERROR: 647 { 648 struct ANASTASIS_ShareResult sr = { 649 .ss = ANASTASIS_SHARE_STATUS_PROVIDER_FAILED, 650 .details.provider_failure.provider_url = pss->anastasis_url, 651 .details.provider_failure.http_status = ud->http_status, 652 .details.provider_failure.ec = ud->ec, 653 }; 654 655 ss->src (ss->src_cls, 656 &sr); 657 ANASTASIS_secret_share_cancel (ss); 658 return; 659 } 660 case ANASTASIS_US_CONFLICTING_TRUTH: 661 GNUNET_break (0); 662 break; 663 } 664 for (unsigned int i = 0; i<ss->pss_length; i++) 665 if (NULL != ss->pss[i].pso) 666 /* some upload is still pending, let's wait for it to finish */ 667 return; 668 669 { 670 struct ANASTASIS_SharePaymentRequest spr[GNUNET_NZL (ss->pss_length)]; 671 struct ANASTASIS_ProviderSuccessStatus apss[GNUNET_NZL (ss->pss_length)]; 672 unsigned int off = 0; 673 unsigned int voff = 0; 674 struct ANASTASIS_ShareResult sr; 675 676 for (unsigned int i = 0; i<ss->pss_length; i++) 677 { 678 struct PolicyStoreState *pssi = &ss->pss[i]; 679 680 if (NULL == pssi->payment_request) 681 { 682 apss[voff].policy_version = pssi->policy_version; 683 apss[voff].provider_url = pssi->anastasis_url; 684 apss[voff].policy_expiration = pssi->policy_expiration; 685 voff++; 686 } 687 else 688 { 689 spr[off].payment_request_url = pssi->payment_request; 690 spr[off].provider_url = pssi->anastasis_url; 691 spr[off].payment_secret = pssi->payment_secret; 692 off++; 693 } 694 } 695 if (off > 0) 696 { 697 sr.ss = ANASTASIS_SHARE_STATUS_PAYMENT_REQUIRED; 698 sr.details.payment_required.payment_requests = spr; 699 sr.details.payment_required.payment_requests_length = off; 700 } 701 else 702 { 703 sr.ss = ANASTASIS_SHARE_STATUS_SUCCESS; 704 sr.details.success.pss = apss; 705 sr.details.success.num_providers = voff; 706 } 707 ss->src (ss->src_cls, 708 &sr); 709 } 710 ANASTASIS_secret_share_cancel (ss); 711 } 712 713 714 struct ANASTASIS_SecretShare * 715 ANASTASIS_secret_share (struct GNUNET_CURL_Context *ctx, 716 const json_t *id_data, 717 const struct ANASTASIS_ProviderDetails providers[], 718 unsigned int pss_length, 719 const struct ANASTASIS_Policy *policies[], 720 unsigned int policies_len, 721 uint32_t payment_years_requested, 722 struct GNUNET_TIME_Relative pay_timeout, 723 ANASTASIS_ShareResultCallback src, 724 void *src_cls, 725 const char *secret_name, 726 const void *core_secret, 727 size_t core_secret_size) 728 { 729 struct ANASTASIS_SecretShare *ss; 730 struct ANASTASIS_CoreSecretEncryptionResult *cser; 731 json_t *dec_policies; 732 json_t *esc_methods; 733 size_t recovery_document_size; 734 char *recovery_document_str; 735 size_t meta_size; 736 void *meta; 737 738 if (0 == pss_length) 739 { 740 GNUNET_break (0); 741 return NULL; 742 } 743 ss = GNUNET_new (struct ANASTASIS_SecretShare); 744 ss->src = src; 745 ss->src_cls = src_cls; 746 ss->pss = GNUNET_new_array (pss_length, 747 struct PolicyStoreState); 748 ss->pss_length = pss_length; 749 ss->ctx = ctx; 750 751 { 752 struct ANASTASIS_CRYPTO_PolicyKeyP policy_keys[GNUNET_NZL (policies_len)]; 753 754 for (unsigned int i = 0; i < policies_len; i++) 755 policy_keys[i] = policies[i]->policy_key; 756 cser = ANASTASIS_CRYPTO_core_secret_encrypt (policy_keys, 757 policies_len, 758 core_secret, 759 core_secret_size); 760 } 761 dec_policies = json_array (); 762 GNUNET_assert (NULL != dec_policies); 763 for (unsigned int k = 0; k < policies_len; k++) 764 { 765 const struct ANASTASIS_Policy *policy = policies[k]; 766 json_t *uuids = json_array (); 767 768 GNUNET_assert (NULL != uuids); 769 for (unsigned int b = 0; b < policy->truths_length; b++) 770 GNUNET_assert (0 == 771 json_array_append_new ( 772 uuids, 773 GNUNET_JSON_from_data_auto ( 774 &policy->truths[b]->uuid))); 775 GNUNET_assert (0 == 776 json_array_append_new ( 777 dec_policies, 778 GNUNET_JSON_PACK ( 779 GNUNET_JSON_pack_data_varsize ("master_key", 780 cser->enc_master_keys[k], 781 cser->enc_master_key_sizes 782 [k]), 783 GNUNET_JSON_pack_array_steal ("uuids", 784 uuids), 785 GNUNET_JSON_pack_data_auto ("master_salt", 786 &policy->master_salt)))); 787 } 788 789 esc_methods = json_array (); 790 GNUNET_assert (NULL != esc_methods); 791 for (unsigned int k = 0; k < policies_len; k++) 792 { 793 const struct ANASTASIS_Policy *policy = policies[k]; 794 795 for (unsigned int l = 0; l < policy->truths_length; l++) 796 { 797 const struct ANASTASIS_Truth *pt = policy->truths[l]; 798 bool unique = true; 799 800 /* Only append each truth once */ 801 for (unsigned int k2 = 0; k2 < k; k2++) 802 { 803 const struct ANASTASIS_Policy *p2 = policies[k2]; 804 for (unsigned int l2 = 0; l2 < p2->truths_length; l2++) 805 if (0 == 806 GNUNET_memcmp (&pt->uuid, 807 &p2->truths[l2]->uuid)) 808 { 809 unique = false; 810 break; 811 } 812 if (! unique) 813 break; 814 } 815 if (! unique) 816 continue; 817 818 GNUNET_assert (0 == 819 json_array_append_new ( 820 esc_methods, 821 GNUNET_JSON_PACK ( 822 GNUNET_JSON_pack_data_auto ("uuid", 823 &pt->uuid), 824 GNUNET_JSON_pack_string ("url", 825 pt->url), 826 GNUNET_JSON_pack_string ("instructions", 827 pt->instructions), 828 GNUNET_JSON_pack_data_auto ("truth_key", 829 &pt->truth_key), 830 GNUNET_JSON_pack_data_auto ("question_salt", 831 &pt->question_salt), 832 GNUNET_JSON_pack_data_auto ("provider_salt", 833 &pt->provider_salt), 834 GNUNET_JSON_pack_string ("escrow_type", 835 pt->type)))); 836 } 837 } 838 839 { 840 json_t *recovery_document; 841 size_t rd_size; 842 char *rd_str; 843 Bytef *cbuf; 844 uLongf cbuf_size; 845 int ret; 846 uint32_t be_size; 847 848 recovery_document = GNUNET_JSON_PACK ( 849 GNUNET_JSON_pack_allow_null ( 850 GNUNET_JSON_pack_string ("secret_name", 851 secret_name)), 852 GNUNET_JSON_pack_array_steal ("policies", 853 dec_policies), 854 GNUNET_JSON_pack_array_steal ("escrow_methods", 855 esc_methods), 856 GNUNET_JSON_pack_data_varsize ("encrypted_core_secret", 857 cser->enc_core_secret, 858 cser->enc_core_secret_size)); 859 GNUNET_assert (NULL != recovery_document); 860 ANASTASIS_CRYPTO_destroy_encrypted_core_secret (cser); 861 cser = NULL; 862 863 rd_str = json_dumps (recovery_document, 864 JSON_COMPACT | JSON_SORT_KEYS); 865 GNUNET_assert (NULL != rd_str); 866 json_decref (recovery_document); 867 rd_size = strlen (rd_str); 868 cbuf_size = compressBound (rd_size); 869 be_size = htonl ((uint32_t) rd_size); 870 cbuf = GNUNET_malloc (cbuf_size + sizeof (uint32_t)); 871 memcpy (cbuf, 872 &be_size, 873 sizeof (uint32_t)); 874 ret = compress (cbuf + sizeof (uint32_t), 875 &cbuf_size, 876 (const Bytef *) rd_str, 877 rd_size); 878 if (Z_OK != ret) 879 { 880 /* compression failed!? */ 881 GNUNET_break (0); 882 free (rd_str); 883 GNUNET_free (cbuf); 884 ANASTASIS_secret_share_cancel (ss); 885 return NULL; 886 } 887 free (rd_str); 888 recovery_document_size = (size_t) (cbuf_size + sizeof (uint32_t)); 889 recovery_document_str = (char *) cbuf; 890 } 891 892 meta_size = sizeof (struct GNUNET_HashCode); 893 if (NULL != secret_name) 894 meta_size += strlen (secret_name) + 1; 895 meta = GNUNET_malloc (meta_size); 896 GNUNET_CRYPTO_hash (recovery_document_str, 897 recovery_document_size, 898 (struct GNUNET_HashCode *) meta); 899 if (NULL != secret_name) 900 memcpy (meta + sizeof (struct GNUNET_HashCode), 901 secret_name, 902 strlen (secret_name) + 1); 903 904 for (unsigned int l = 0; l < ss->pss_length; l++) 905 { 906 struct PolicyStoreState *pss = &ss->pss[l]; 907 void *recovery_data; 908 size_t recovery_data_size; 909 struct ANASTASIS_CRYPTO_AccountPrivateKeyP anastasis_priv; 910 size_t enc_meta_size = 0; 911 void *enc_meta = NULL; 912 913 pss->ss = ss; 914 pss->anastasis_url = GNUNET_strdup (providers[l].provider_url); 915 pss->provider_salt = providers[l].provider_salt; 916 pss->payment_secret = providers[l].payment_secret; 917 ANASTASIS_CRYPTO_user_identifier_derive (id_data, 918 &pss->provider_salt, 919 &pss->id); 920 ANASTASIS_CRYPTO_recovery_metadata_encrypt (&pss->id, 921 meta, 922 meta_size, 923 &enc_meta, 924 &enc_meta_size); 925 ANASTASIS_CRYPTO_account_private_key_derive (&pss->id, 926 &anastasis_priv); 927 ANASTASIS_CRYPTO_recovery_document_encrypt (&pss->id, 928 recovery_document_str, 929 recovery_document_size, 930 &recovery_data, 931 &recovery_data_size); 932 GNUNET_CRYPTO_hash (recovery_data, 933 recovery_data_size, 934 &pss->curr_hash); 935 pss->pso = ANASTASIS_policy_store ( 936 ss->ctx, 937 pss->anastasis_url, 938 &anastasis_priv, 939 recovery_data, 940 recovery_data_size, 941 enc_meta, 942 enc_meta_size, 943 payment_years_requested, 944 (! GNUNET_is_zero (&pss->payment_secret)) 945 ? &pss->payment_secret 946 : NULL, 947 pay_timeout, 948 &policy_store_cb, 949 pss); 950 GNUNET_free (recovery_data); 951 GNUNET_free (enc_meta); 952 if (NULL == pss->pso) 953 { 954 GNUNET_break (0); 955 ANASTASIS_secret_share_cancel (ss); 956 GNUNET_free (recovery_document_str); 957 GNUNET_free (meta); 958 return NULL; 959 } 960 } 961 GNUNET_free (meta); 962 GNUNET_free (recovery_document_str); 963 return ss; 964 } 965 966 967 void 968 ANASTASIS_secret_share_cancel (struct ANASTASIS_SecretShare *ss) 969 { 970 for (unsigned int i = 0; i<ss->pss_length; i++) 971 { 972 struct PolicyStoreState *pssi = &ss->pss[i]; 973 974 if (NULL != pssi->pso) 975 { 976 ANASTASIS_policy_store_cancel (pssi->pso); 977 pssi->pso = NULL; 978 } 979 GNUNET_free (pssi->anastasis_url); 980 GNUNET_free (pssi->payment_request); 981 } 982 GNUNET_free (ss->pss); 983 GNUNET_free (ss); 984 }