anastasis_backup.c (29055B)
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 (&nonce, 375 sizeof (nonce)); 376 GNUNET_CRYPTO_random_block (&question_salt, 377 sizeof (question_salt)); 378 GNUNET_CRYPTO_random_block (&uuid, 379 sizeof (uuid)); 380 GNUNET_CRYPTO_random_block (&truth_key, 381 sizeof (truth_key)); 382 ANASTASIS_CRYPTO_keyshare_create (&key_share); 383 return ANASTASIS_truth_upload2 (ctx, 384 user_id, 385 provider_url, 386 type, 387 instructions, 388 mime_type, 389 provider_salt, 390 truth_data, 391 truth_data_size, 392 payment_years_requested, 393 pay_timeout, 394 &nonce, 395 &uuid, 396 &question_salt, 397 &truth_key, 398 &key_share, 399 tc, 400 tc_cls); 401 } 402 403 404 void 405 ANASTASIS_truth_upload_cancel (struct ANASTASIS_TruthUpload *tu) 406 { 407 if (NULL != tu->tso) 408 { 409 ANASTASIS_truth_store_cancel (tu->tso); 410 tu->tso = NULL; 411 } 412 if (NULL != tu->t) 413 { 414 ANASTASIS_truth_free (tu->t); 415 tu->t = NULL; 416 } 417 GNUNET_free (tu); 418 } 419 420 421 void 422 ANASTASIS_truth_free (struct ANASTASIS_Truth *t) 423 { 424 GNUNET_free (t->url); 425 GNUNET_free (t->type); 426 GNUNET_free (t->instructions); 427 GNUNET_free (t->mime_type); 428 GNUNET_free (t); 429 } 430 431 432 struct ANASTASIS_Policy 433 { 434 /** 435 * Encrypted policy master key 436 */ 437 struct ANASTASIS_CRYPTO_PolicyKeyP policy_key; 438 439 /** 440 * Salt used to encrypt the master key 441 */ 442 struct ANASTASIS_CRYPTO_MasterSaltP master_salt; 443 444 /** 445 * Array of truths 446 */ 447 struct ANASTASIS_Truth **truths; 448 449 /** 450 * Length of @ truths array. 451 */ 452 uint32_t truths_length; 453 454 }; 455 456 457 /** 458 * Duplicate truth object. 459 * 460 * @param t object to duplicate 461 * @return copy of @a t 462 */ 463 static struct ANASTASIS_Truth * 464 truth_dup (const struct ANASTASIS_Truth *t) 465 { 466 struct ANASTASIS_Truth *d = GNUNET_new (struct ANASTASIS_Truth); 467 468 *d = *t; 469 d->url = GNUNET_strdup (t->url); 470 d->type = GNUNET_strdup (t->type); 471 d->instructions = GNUNET_strdup (t->instructions); 472 if (NULL != t->mime_type) 473 d->mime_type = GNUNET_strdup (t->mime_type); 474 return d; 475 } 476 477 478 struct ANASTASIS_Policy * 479 ANASTASIS_policy_create (const struct ANASTASIS_Truth *truths[], 480 unsigned int truths_len) 481 { 482 struct ANASTASIS_Policy *p; 483 484 p = GNUNET_new (struct ANASTASIS_Policy); 485 GNUNET_CRYPTO_random_block (&p->master_salt, 486 sizeof (p->master_salt)); 487 { 488 struct ANASTASIS_CRYPTO_KeyShareP key_shares[truths_len]; 489 490 for (unsigned int i = 0; i < truths_len; i++) 491 key_shares[i] = truths[i]->key_share; 492 ANASTASIS_CRYPTO_policy_key_derive (key_shares, 493 truths_len, 494 &p->master_salt, 495 &p->policy_key); 496 } 497 p->truths = GNUNET_new_array (truths_len, 498 struct ANASTASIS_Truth *); 499 for (unsigned int i = 0; i<truths_len; i++) 500 p->truths[i] = truth_dup (truths[i]); 501 p->truths_length = truths_len; 502 return p; 503 } 504 505 506 void 507 ANASTASIS_policy_destroy (struct ANASTASIS_Policy *p) 508 { 509 for (unsigned int i = 0; i<p->truths_length; i++) 510 ANASTASIS_truth_free (p->truths[i]); 511 GNUNET_free (p->truths); 512 GNUNET_free (p); 513 } 514 515 516 /** 517 * State for a "policy store" CMD. 518 */ 519 struct PolicyStoreState 520 { 521 /** 522 * User identifier used as entropy source for the account public key 523 */ 524 struct ANASTASIS_CRYPTO_UserIdentifierP id; 525 526 /** 527 * Hash of the current upload. Used to check the server's response. 528 */ 529 struct GNUNET_HashCode curr_hash; 530 531 /** 532 * Payment identifier. 533 */ 534 struct ANASTASIS_PaymentSecretP payment_secret; 535 536 /** 537 * Server salt. Points into a truth object from which we got the 538 * salt. 539 */ 540 struct ANASTASIS_CRYPTO_ProviderSaltP provider_salt; 541 542 /** 543 * The /policy POST operation handle. 544 */ 545 struct ANASTASIS_PolicyStoreOperation *pso; 546 547 /** 548 * URL of the anastasis backend. 549 */ 550 char *anastasis_url; 551 552 /** 553 * Payment request returned by this provider, if any. 554 */ 555 char *payment_request; 556 557 /** 558 * reference to SecretShare 559 */ 560 struct ANASTASIS_SecretShare *ss; 561 562 /** 563 * Version of the policy created at the provider. 564 */ 565 unsigned long long policy_version; 566 567 /** 568 * When will the policy expire at the provider. 569 */ 570 struct GNUNET_TIME_Timestamp policy_expiration; 571 572 }; 573 574 /** 575 * Defines a recovery document upload process (recovery document consists of multiple policies) 576 */ 577 struct ANASTASIS_SecretShare 578 { 579 /** 580 * Closure for the Result Callback 581 */ 582 struct GNUNET_CURL_Context *ctx; 583 584 /** 585 * Callback which gives back the result of the POST Request 586 */ 587 ANASTASIS_ShareResultCallback src; 588 589 /** 590 * Closure for the Result Callback 591 */ 592 void *src_cls; 593 594 /** 595 * References for the upload states and operations (size of truths passed) 596 */ 597 struct PolicyStoreState *pss; 598 599 /** 600 * Closure for the Result Callback 601 */ 602 unsigned int pss_length; 603 }; 604 605 606 /** 607 * Callback to process a POST /policy request 608 * 609 * @param cls closure 610 * @param ud the decoded response body 611 */ 612 static void 613 policy_store_cb (void *cls, 614 const struct ANASTASIS_UploadDetails *ud) 615 { 616 struct PolicyStoreState *pss = cls; 617 struct ANASTASIS_SecretShare *ss = pss->ss; 618 enum ANASTASIS_UploadStatus us; 619 620 pss->pso = NULL; 621 us = ud->us; 622 if ( (ANASTASIS_US_SUCCESS == us) && 623 (0 != GNUNET_memcmp (&pss->curr_hash, 624 ud->details.success.curr_backup_hash)) ) 625 { 626 GNUNET_break_op (0); 627 us = ANASTASIS_US_SERVER_ERROR; 628 } 629 switch (us) 630 { 631 case ANASTASIS_US_SUCCESS: 632 pss->policy_version = ud->details.success.policy_version; 633 pss->policy_expiration = ud->details.success.policy_expiration; 634 break; 635 case ANASTASIS_US_PAYMENT_REQUIRED: 636 pss->payment_request = GNUNET_strdup (ud->details.payment.payment_request); 637 pss->payment_secret = ud->details.payment.ps; 638 break; 639 case ANASTASIS_US_HTTP_ERROR: 640 case ANASTASIS_US_CLIENT_ERROR: 641 case ANASTASIS_US_SERVER_ERROR: 642 { 643 struct ANASTASIS_ShareResult sr = { 644 .ss = ANASTASIS_SHARE_STATUS_PROVIDER_FAILED, 645 .details.provider_failure.provider_url = pss->anastasis_url, 646 .details.provider_failure.http_status = ud->http_status, 647 .details.provider_failure.ec = ud->ec, 648 }; 649 650 ss->src (ss->src_cls, 651 &sr); 652 ANASTASIS_secret_share_cancel (ss); 653 return; 654 } 655 case ANASTASIS_US_CONFLICTING_TRUTH: 656 GNUNET_break (0); 657 break; 658 } 659 for (unsigned int i = 0; i<ss->pss_length; i++) 660 if (NULL != ss->pss[i].pso) 661 /* some upload is still pending, let's wait for it to finish */ 662 return; 663 664 { 665 struct ANASTASIS_SharePaymentRequest spr[GNUNET_NZL (ss->pss_length)]; 666 struct ANASTASIS_ProviderSuccessStatus apss[GNUNET_NZL (ss->pss_length)]; 667 unsigned int off = 0; 668 unsigned int voff = 0; 669 struct ANASTASIS_ShareResult sr; 670 671 for (unsigned int i = 0; i<ss->pss_length; i++) 672 { 673 struct PolicyStoreState *pssi = &ss->pss[i]; 674 675 if (NULL == pssi->payment_request) 676 { 677 apss[voff].policy_version = pssi->policy_version; 678 apss[voff].provider_url = pssi->anastasis_url; 679 apss[voff].policy_expiration = pssi->policy_expiration; 680 voff++; 681 } 682 else 683 { 684 spr[off].payment_request_url = pssi->payment_request; 685 spr[off].provider_url = pssi->anastasis_url; 686 spr[off].payment_secret = pssi->payment_secret; 687 off++; 688 } 689 } 690 if (off > 0) 691 { 692 sr.ss = ANASTASIS_SHARE_STATUS_PAYMENT_REQUIRED; 693 sr.details.payment_required.payment_requests = spr; 694 sr.details.payment_required.payment_requests_length = off; 695 } 696 else 697 { 698 sr.ss = ANASTASIS_SHARE_STATUS_SUCCESS; 699 sr.details.success.pss = apss; 700 sr.details.success.num_providers = voff; 701 } 702 ss->src (ss->src_cls, 703 &sr); 704 } 705 ANASTASIS_secret_share_cancel (ss); 706 } 707 708 709 struct ANASTASIS_SecretShare * 710 ANASTASIS_secret_share (struct GNUNET_CURL_Context *ctx, 711 const json_t *id_data, 712 const struct ANASTASIS_ProviderDetails providers[], 713 unsigned int pss_length, 714 const struct ANASTASIS_Policy *policies[], 715 unsigned int policies_len, 716 uint32_t payment_years_requested, 717 struct GNUNET_TIME_Relative pay_timeout, 718 ANASTASIS_ShareResultCallback src, 719 void *src_cls, 720 const char *secret_name, 721 const void *core_secret, 722 size_t core_secret_size) 723 { 724 struct ANASTASIS_SecretShare *ss; 725 struct ANASTASIS_CoreSecretEncryptionResult *cser; 726 json_t *dec_policies; 727 json_t *esc_methods; 728 size_t recovery_document_size; 729 char *recovery_document_str; 730 size_t meta_size; 731 void *meta; 732 733 if (0 == pss_length) 734 { 735 GNUNET_break (0); 736 return NULL; 737 } 738 ss = GNUNET_new (struct ANASTASIS_SecretShare); 739 ss->src = src; 740 ss->src_cls = src_cls; 741 ss->pss = GNUNET_new_array (pss_length, 742 struct PolicyStoreState); 743 ss->pss_length = pss_length; 744 ss->ctx = ctx; 745 746 { 747 struct ANASTASIS_CRYPTO_PolicyKeyP policy_keys[GNUNET_NZL (policies_len)]; 748 749 for (unsigned int i = 0; i < policies_len; i++) 750 policy_keys[i] = policies[i]->policy_key; 751 cser = ANASTASIS_CRYPTO_core_secret_encrypt (policy_keys, 752 policies_len, 753 core_secret, 754 core_secret_size); 755 } 756 dec_policies = json_array (); 757 GNUNET_assert (NULL != dec_policies); 758 for (unsigned int k = 0; k < policies_len; k++) 759 { 760 const struct ANASTASIS_Policy *policy = policies[k]; 761 json_t *uuids = json_array (); 762 763 GNUNET_assert (NULL != uuids); 764 for (unsigned int b = 0; b < policy->truths_length; b++) 765 GNUNET_assert (0 == 766 json_array_append_new ( 767 uuids, 768 GNUNET_JSON_from_data_auto ( 769 &policy->truths[b]->uuid))); 770 GNUNET_assert (0 == 771 json_array_append_new ( 772 dec_policies, 773 GNUNET_JSON_PACK ( 774 GNUNET_JSON_pack_data_varsize ("master_key", 775 cser->enc_master_keys[k], 776 cser->enc_master_key_sizes 777 [k]), 778 GNUNET_JSON_pack_array_steal ("uuids", 779 uuids), 780 GNUNET_JSON_pack_data_auto ("master_salt", 781 &policy->master_salt)))); 782 } 783 784 esc_methods = json_array (); 785 GNUNET_assert (NULL != esc_methods); 786 for (unsigned int k = 0; k < policies_len; k++) 787 { 788 const struct ANASTASIS_Policy *policy = policies[k]; 789 790 for (unsigned int l = 0; l < policy->truths_length; l++) 791 { 792 const struct ANASTASIS_Truth *pt = policy->truths[l]; 793 bool unique = true; 794 795 /* Only append each truth once */ 796 for (unsigned int k2 = 0; k2 < k; k2++) 797 { 798 const struct ANASTASIS_Policy *p2 = policies[k2]; 799 for (unsigned int l2 = 0; l2 < p2->truths_length; l2++) 800 if (0 == 801 GNUNET_memcmp (&pt->uuid, 802 &p2->truths[l2]->uuid)) 803 { 804 unique = false; 805 break; 806 } 807 if (! unique) 808 break; 809 } 810 if (! unique) 811 continue; 812 813 GNUNET_assert (0 == 814 json_array_append_new ( 815 esc_methods, 816 GNUNET_JSON_PACK ( 817 GNUNET_JSON_pack_data_auto ("uuid", 818 &pt->uuid), 819 GNUNET_JSON_pack_string ("url", 820 pt->url), 821 GNUNET_JSON_pack_string ("instructions", 822 pt->instructions), 823 GNUNET_JSON_pack_data_auto ("truth_key", 824 &pt->truth_key), 825 GNUNET_JSON_pack_data_auto ("question_salt", 826 &pt->question_salt), 827 GNUNET_JSON_pack_data_auto ("provider_salt", 828 &pt->provider_salt), 829 GNUNET_JSON_pack_string ("escrow_type", 830 pt->type)))); 831 } 832 } 833 834 { 835 json_t *recovery_document; 836 size_t rd_size; 837 char *rd_str; 838 Bytef *cbuf; 839 uLongf cbuf_size; 840 int ret; 841 uint32_t be_size; 842 843 recovery_document = GNUNET_JSON_PACK ( 844 GNUNET_JSON_pack_allow_null ( 845 GNUNET_JSON_pack_string ("secret_name", 846 secret_name)), 847 GNUNET_JSON_pack_array_steal ("policies", 848 dec_policies), 849 GNUNET_JSON_pack_array_steal ("escrow_methods", 850 esc_methods), 851 GNUNET_JSON_pack_data_varsize ("encrypted_core_secret", 852 cser->enc_core_secret, 853 cser->enc_core_secret_size)); 854 GNUNET_assert (NULL != recovery_document); 855 ANASTASIS_CRYPTO_destroy_encrypted_core_secret (cser); 856 cser = NULL; 857 858 rd_str = json_dumps (recovery_document, 859 JSON_COMPACT | JSON_SORT_KEYS); 860 GNUNET_assert (NULL != rd_str); 861 json_decref (recovery_document); 862 rd_size = strlen (rd_str); 863 cbuf_size = compressBound (rd_size); 864 be_size = htonl ((uint32_t) rd_size); 865 cbuf = GNUNET_malloc (cbuf_size + sizeof (uint32_t)); 866 memcpy (cbuf, 867 &be_size, 868 sizeof (uint32_t)); 869 ret = compress (cbuf + sizeof (uint32_t), 870 &cbuf_size, 871 (const Bytef *) rd_str, 872 rd_size); 873 if (Z_OK != ret) 874 { 875 /* compression failed!? */ 876 GNUNET_break (0); 877 free (rd_str); 878 GNUNET_free (cbuf); 879 ANASTASIS_secret_share_cancel (ss); 880 return NULL; 881 } 882 free (rd_str); 883 recovery_document_size = (size_t) (cbuf_size + sizeof (uint32_t)); 884 recovery_document_str = (char *) cbuf; 885 } 886 887 meta_size = sizeof (struct GNUNET_HashCode); 888 if (NULL != secret_name) 889 meta_size += strlen (secret_name) + 1; 890 meta = GNUNET_malloc (meta_size); 891 GNUNET_CRYPTO_hash (recovery_document_str, 892 recovery_document_size, 893 (struct GNUNET_HashCode *) meta); 894 if (NULL != secret_name) 895 memcpy (meta + sizeof (struct GNUNET_HashCode), 896 secret_name, 897 strlen (secret_name) + 1); 898 899 for (unsigned int l = 0; l < ss->pss_length; l++) 900 { 901 struct PolicyStoreState *pss = &ss->pss[l]; 902 void *recovery_data; 903 size_t recovery_data_size; 904 struct ANASTASIS_CRYPTO_AccountPrivateKeyP anastasis_priv; 905 size_t enc_meta_size = 0; 906 void *enc_meta = NULL; 907 908 pss->ss = ss; 909 pss->anastasis_url = GNUNET_strdup (providers[l].provider_url); 910 pss->provider_salt = providers[l].provider_salt; 911 pss->payment_secret = providers[l].payment_secret; 912 ANASTASIS_CRYPTO_user_identifier_derive (id_data, 913 &pss->provider_salt, 914 &pss->id); 915 ANASTASIS_CRYPTO_recovery_metadata_encrypt (&pss->id, 916 meta, 917 meta_size, 918 &enc_meta, 919 &enc_meta_size); 920 ANASTASIS_CRYPTO_account_private_key_derive (&pss->id, 921 &anastasis_priv); 922 ANASTASIS_CRYPTO_recovery_document_encrypt (&pss->id, 923 recovery_document_str, 924 recovery_document_size, 925 &recovery_data, 926 &recovery_data_size); 927 GNUNET_CRYPTO_hash (recovery_data, 928 recovery_data_size, 929 &pss->curr_hash); 930 pss->pso = ANASTASIS_policy_store ( 931 ss->ctx, 932 pss->anastasis_url, 933 &anastasis_priv, 934 recovery_data, 935 recovery_data_size, 936 enc_meta, 937 enc_meta_size, 938 payment_years_requested, 939 (! GNUNET_is_zero (&pss->payment_secret)) 940 ? &pss->payment_secret 941 : NULL, 942 pay_timeout, 943 &policy_store_cb, 944 pss); 945 GNUNET_free (recovery_data); 946 GNUNET_free (enc_meta); 947 if (NULL == pss->pso) 948 { 949 GNUNET_break (0); 950 ANASTASIS_secret_share_cancel (ss); 951 GNUNET_free (recovery_document_str); 952 GNUNET_free (meta); 953 return NULL; 954 } 955 } 956 GNUNET_free (meta); 957 GNUNET_free (recovery_document_str); 958 return ss; 959 } 960 961 962 void 963 ANASTASIS_secret_share_cancel (struct ANASTASIS_SecretShare *ss) 964 { 965 for (unsigned int i = 0; i<ss->pss_length; i++) 966 { 967 struct PolicyStoreState *pssi = &ss->pss[i]; 968 969 if (NULL != pssi->pso) 970 { 971 ANASTASIS_policy_store_cancel (pssi->pso); 972 pssi->pso = NULL; 973 } 974 GNUNET_free (pssi->anastasis_url); 975 GNUNET_free (pssi->payment_request); 976 } 977 GNUNET_free (ss->pss); 978 GNUNET_free (ss); 979 }