anastasis_api_redux_state.h (38322B)
1 /* 2 This file is part of Anastasis 3 Copyright (C) 2020, 2021, 2022 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 reducer/anastasis_api_redux_state.h 18 * @brief typed representation of the reducer state 19 * @author Christian Grothoff 20 * 21 * The reducer's public API (`anastasis_redux.h`) speaks JSON, but the reducer 22 * logic itself does not: every entry point parses the incoming JSON into a 23 * `struct ANASTASIS_ReduxState` exactly once, operates on that, and serializes 24 * it back exactly once on the way out. The three generic routines at the 25 * bottom of this file are the only places that know the JSON encoding. 26 * 27 * Parsing is strict: a field that is not described here is an error 28 * (#TALER_EC_ANASTASIS_REDUCER_STATE_INVALID). There are two deliberate 29 * exceptions, both marked `json_t *` below, where the exact bytes the user 30 * supplied are cryptographically load-bearing and must not be normalized: 31 * @e identity_attributes (PoW-hashed to derive the account key) and 32 * @e core_secret (its serialization *is* the uploaded secret). 33 */ 34 #ifndef ANASTASIS_API_REDUX_STATE_H 35 #define ANASTASIS_API_REDUX_STATE_H 36 37 #include "anastasis_redux.h" 38 #include "anastasis_api_redux.h" 39 40 41 /* ************************ Wrapped primitives *********************** */ 42 43 /** 44 * URL of an Anastasis provider. Wrapped so that it cannot be confused 45 * with the many other strings floating around the reducer (business 46 * names, payto URIs, display hints, ...). 47 */ 48 struct ANASTASIS_ProviderUrl 49 { 50 /** 51 * The URL itself. Owned by the containing structure. 52 */ 53 char *url; 54 }; 55 56 57 /** 58 * Index into the @e policies array of a backup state. 59 */ 60 struct ANASTASIS_PolicyIndex 61 { 62 /** 63 * The index. 64 */ 65 unsigned int idx; 66 }; 67 68 69 /** 70 * Index into the @e methods array of a policy, or into the 71 * @e authentication_methods array of a backup state. 72 */ 73 struct ANASTASIS_MethodIndex 74 { 75 /** 76 * The index. 77 */ 78 unsigned int idx; 79 }; 80 81 82 /** 83 * Bitmask selecting which optional identity attributes were used. 84 */ 85 struct ANASTASIS_AttributeMask 86 { 87 /** 88 * The mask. 89 */ 90 uint64_t mask; 91 }; 92 93 94 /* ************************ Geography ******************************** */ 95 96 /** 97 * A continent the user may select. 98 */ 99 struct ANASTASIS_ReduxContinent 100 { 101 /** 102 * Name of the continent, e.g. "Europe". 103 */ 104 char *name; 105 106 /** 107 * Translations of @e name, NULL if not given. An object mapping 108 * language tags to strings, kept verbatim: the reducer only carries 109 * translations from the resource files to the user interface and 110 * never interprets them. 111 */ 112 json_t *name_i18n; 113 114 /** 115 * True if this continent was given as a bare string rather than as 116 * an object. Both forms occur: the reducer itself emits objects, 117 * but hand-written states use plain names. 118 */ 119 bool bare; 120 }; 121 122 123 /** 124 * A country the user may select. Copied verbatim from 125 * `contrib/redux.countries.json`. 126 */ 127 struct ANASTASIS_ReduxCountry 128 { 129 /** 130 * Two-letter country code, e.g. "ch". 131 */ 132 char *code; 133 134 /** 135 * Name of the country. 136 */ 137 char *name; 138 139 /** 140 * Continent the country is on. 141 */ 142 char *continent; 143 144 /** 145 * International dialling prefix, e.g. "+41". 146 */ 147 char *call_code; 148 149 /** 150 * Translations of @e name, NULL if not given. Kept verbatim, see 151 * #ANASTASIS_ReduxContinent. 152 */ 153 json_t *name_i18n; 154 155 /** 156 * Translations of @e continent, NULL if not given. Kept verbatim, 157 * see #ANASTASIS_ReduxContinent. 158 */ 159 json_t *continent_i18n; 160 161 /** 162 * Currency used in this country, NULL if not given. Carried through 163 * for the benefit of user interfaces; the reducer does not use it. 164 */ 165 char *currency; 166 }; 167 168 169 /** 170 * Specification of one identity attribute we ask the user for. 171 * Copied verbatim from `contrib/redux.$CC.json`. 172 */ 173 struct ANASTASIS_ReduxAttributeSpec 174 { 175 /** 176 * Type of the attribute, e.g. "string" or "date". 177 */ 178 char *type; 179 180 /** 181 * Name of the attribute; the key under which the user's answer 182 * appears in @e identity_attributes. 183 */ 184 char *name; 185 186 /** 187 * Human-readable label. 188 */ 189 char *label; 190 191 /** 192 * Widget the GTK UI should use to ask for this attribute. 193 */ 194 char *widget; 195 196 /** 197 * UUID identifying this attribute. 198 */ 199 char *uuid; 200 201 /** 202 * Tooltip for the UI, NULL if not given. 203 */ 204 char *tooltip; 205 206 /** 207 * Regular expression the value must match, NULL if not given. 208 */ 209 char *validation_regex; 210 211 /** 212 * Name of a validation function, resolved against the fixed table in 213 * reducer/validation.c. NULL if not given. 214 */ 215 char *validation_logic; 216 217 /** 218 * Input mask for autocompletion, NULL if not given. 219 */ 220 char *autocomplete; 221 222 /** 223 * Translations of @e label, NULL if not given. Kept verbatim, see 224 * #ANASTASIS_ReduxContinent. 225 */ 226 json_t *label_i18n; 227 228 /** 229 * True if the user may leave this attribute blank. 230 */ 231 bool optional; 232 233 /** 234 * True if @e optional was explicitly present in the JSON. Needed so 235 * that serialization does not invent an `"optional": false` field 236 * where the resource file had none. 237 */ 238 bool have_optional; 239 }; 240 241 242 /* ************************ Providers ******************************** */ 243 244 /** 245 * Status of an Anastasis provider in the reducer state. 246 */ 247 enum ANASTASIS_ReduxProviderStatus 248 { 249 /** 250 * We have not (yet) talked to this provider. 251 */ 252 ANASTASIS_RPS_NOT_CONTACTED = 0, 253 254 /** 255 * We obtained the provider's /config successfully. 256 */ 257 ANASTASIS_RPS_OK = 1, 258 259 /** 260 * The provider was taken out of consideration, typically because an 261 * upload to it failed. Note that any configuration we obtained 262 * earlier is retained (and re-serialized), matching the behaviour of 263 * the JSON-based implementation this replaced. 264 */ 265 ANASTASIS_RPS_DISABLED = 2, 266 267 /** 268 * Talking to the provider failed. 269 */ 270 ANASTASIS_RPS_ERROR = 3 271 }; 272 273 274 /** 275 * One authentication method offered by a provider, with its price. 276 */ 277 struct ANASTASIS_ReduxMethodSpec 278 { 279 /** 280 * Type of the method, e.g. "question" or "sms". 281 */ 282 char *type; 283 284 /** 285 * Fee charged for using this method during recovery, in the provider's 286 * primary currency. 287 */ 288 struct TALER_Amount usage_fee; 289 290 /** 291 * Fee charged for using this method during recovery, one entry per 292 * currency the provider accepts. Never empty: for a provider that 293 * only reports the scalar fee, it holds that one amount. 294 */ 295 struct TALER_AmountList usage_fees; 296 }; 297 298 299 /** 300 * Configuration of a provider, as obtained from its /config endpoint. 301 */ 302 struct ANASTASIS_ReduxProviderConfig 303 { 304 /** 305 * Methods the provider supports. 306 */ 307 struct ANASTASIS_ReduxMethodSpec *methods; 308 309 /** 310 * Length of the @e methods array. 311 */ 312 unsigned int methods_len; 313 314 /** 315 * Fee for storing a policy for a year, in the primary currency. 316 */ 317 struct TALER_Amount annual_fee; 318 319 /** 320 * Fee for storing a policy for a year, per currency. Never empty. 321 */ 322 struct TALER_AmountList annual_fees; 323 324 /** 325 * Fee for uploading one truth, in the primary currency. 326 */ 327 struct TALER_Amount truth_upload_fee; 328 329 /** 330 * Fee for uploading one truth, per currency. Never empty. 331 */ 332 struct TALER_AmountList truth_upload_fees; 333 334 /** 335 * Maximum liability the provider accepts for data loss, in the primary 336 * currency. 337 */ 338 struct TALER_Amount liability_limit; 339 340 /** 341 * Maximum liability the provider accepts for data loss, per currency. 342 * Never empty. 343 */ 344 struct TALER_AmountList liability_limits; 345 346 /** 347 * Currencies the provider accepts, primary currency first. Never 348 * empty; for a provider that predates multi-currency support it holds 349 * the single currency it quotes everything in. 350 */ 351 char **currencies; 352 353 /** 354 * Length of the @e currencies array. 355 */ 356 unsigned int currencies_len; 357 358 /** 359 * Salt of this provider. 360 */ 361 struct ANASTASIS_CRYPTO_ProviderSaltP provider_salt; 362 363 /** 364 * Business name of the provider. 365 */ 366 char *business_name; 367 368 /** 369 * Currency the provider charges in, NULL if not given. Carried 370 * through for the benefit of user interfaces; @e currencies is the 371 * authoritative list and this is its first entry. 372 */ 373 char *currency; 374 375 /** 376 * Maximum upload size the provider accepts, in megabytes. 377 */ 378 uint32_t storage_limit_in_megabytes; 379 380 /** 381 * HTTP status of the /config request. 382 */ 383 uint32_t http_status; 384 }; 385 386 387 /** 388 * Why we could not use a provider. 389 */ 390 struct ANASTASIS_ReduxProviderError 391 { 392 /** 393 * Error code of the failed request. 394 */ 395 enum TALER_ErrorCode ec; 396 397 /** 398 * HTTP status of the failed request, 0 if we never got one. 399 */ 400 uint32_t http_status; 401 }; 402 403 404 /** 405 * An Anastasis provider we know about. Serializes as one entry of the 406 * `authentication_providers` object, keyed by @e url. 407 */ 408 struct ANASTASIS_ReduxProvider 409 { 410 /** 411 * URL of the provider; the key this entry is stored under. 412 */ 413 struct ANASTASIS_ProviderUrl url; 414 415 /** 416 * What we know about this provider. 417 */ 418 enum ANASTASIS_ReduxProviderStatus status; 419 420 /** 421 * True if @e config is valid. Set whenever a /config reply was 422 * obtained, and *not* cleared when @e status becomes 423 * #ANASTASIS_RPS_DISABLED. 424 */ 425 bool have_config; 426 427 /** 428 * Configuration of the provider; valid iff @e have_config. 429 */ 430 struct ANASTASIS_ReduxProviderConfig config; 431 432 /** 433 * Failure details; valid iff @e status is #ANASTASIS_RPS_ERROR. 434 */ 435 struct ANASTASIS_ReduxProviderError error; 436 }; 437 438 439 /* ******************** Backup-specific state ************************ */ 440 441 /** 442 * An authentication method the user configured. 443 */ 444 struct ANASTASIS_ReduxAuthMethod 445 { 446 /** 447 * Type of the method, e.g. "question". 448 */ 449 char *type; 450 451 /** 452 * Instructions to show the user during recovery. 453 */ 454 char *instructions; 455 456 /** 457 * The challenge itself (answer, phone number, e-mail address, ...). 458 */ 459 void *challenge; 460 461 /** 462 * Number of bytes in @e challenge. 463 */ 464 size_t challenge_size; 465 466 /** 467 * MIME type of @e challenge, NULL if not given. 468 */ 469 char *mime_type; 470 }; 471 472 473 /** 474 * One member of a policy: authenticate with method 475 * @e authentication_method at provider @e provider. 476 */ 477 struct ANASTASIS_ReduxPolicyMethod 478 { 479 /** 480 * Index into the backup state's @e authentication_methods array. 481 */ 482 struct ANASTASIS_MethodIndex authentication_method; 483 484 /** 485 * Provider that stores the key share for this method. 486 */ 487 struct ANASTASIS_ProviderUrl provider; 488 489 /** 490 * Truth uploaded for this method, NULL until the upload happened. 491 * Owned by this structure; freed with ANASTASIS_truth_free(). 492 */ 493 struct ANASTASIS_Truth *truth; 494 495 /** 496 * Status of the upload of @e truth; only meaningful if @e truth is 497 * non-NULL. 498 */ 499 enum ANASTASIS_UploadStatus upload_status; 500 }; 501 502 503 /** 504 * A recovery policy: a set of methods that together recover the secret. 505 */ 506 struct ANASTASIS_ReduxPolicy 507 { 508 /** 509 * Methods that make up this policy. 510 */ 511 struct ANASTASIS_ReduxPolicyMethod *methods; 512 513 /** 514 * Length of the @e methods array. 515 */ 516 unsigned int methods_len; 517 518 /** 519 * What recovering via this policy would cost; only valid if 520 * @e have_recovery_cost. Carried through for user interfaces. 521 */ 522 struct TALER_Amount recovery_cost; 523 524 /** 525 * True if @e recovery_cost was given. 526 */ 527 bool have_recovery_cost; 528 }; 529 530 531 /** 532 * A provider we intend to store the recovery document at. 533 */ 534 struct ANASTASIS_ReduxPolicyProvider 535 { 536 /** 537 * URL of the provider. 538 */ 539 struct ANASTASIS_ProviderUrl provider_url; 540 541 /** 542 * Payment secret remembered from an earlier payment request; only 543 * valid if @e have_payment_secret. 544 */ 545 struct ANASTASIS_PaymentSecretP payment_secret; 546 547 /** 548 * True if @e payment_secret is set. 549 */ 550 bool have_payment_secret; 551 }; 552 553 554 /** 555 * Result of a successful policy upload at one provider. 556 */ 557 struct ANASTASIS_ReduxSuccessDetail 558 { 559 /** 560 * URL of the provider; the key this entry is stored under. 561 */ 562 struct ANASTASIS_ProviderUrl provider_url; 563 564 /** 565 * When the stored policy expires. 566 */ 567 struct GNUNET_TIME_Timestamp policy_expiration; 568 569 /** 570 * Version the policy was stored under. 571 */ 572 uint32_t policy_version; 573 }; 574 575 576 /** 577 * A payment we are asking the application to make for a policy upload. 578 */ 579 struct ANASTASIS_ReduxPolicyPaymentRequest 580 { 581 /** 582 * Payment request URI. 583 */ 584 char *payto; 585 586 /** 587 * Provider that wants to be paid. 588 */ 589 struct ANASTASIS_ProviderUrl provider; 590 }; 591 592 593 /** 594 * Arguments the application passed to the most recent "pay" action. 595 */ 596 struct ANASTASIS_ReduxPayArguments 597 { 598 /** 599 * How long to wait for the payment to go through. 600 */ 601 struct GNUNET_TIME_Relative timeout; 602 603 /** 604 * True if @e timeout was given. 605 */ 606 bool have_timeout; 607 }; 608 609 610 /** 611 * The `backup` variant of the reducer state. 612 */ 613 struct ANASTASIS_ReduxBackup 614 { 615 /** 616 * Which step of the backup process we are at. 617 */ 618 enum ANASTASIS_BackupState state; 619 620 /** 621 * Authentication methods the user configured. 622 */ 623 struct ANASTASIS_ReduxAuthMethod *authentication_methods; 624 625 /** 626 * Length of the @e authentication_methods array. 627 */ 628 unsigned int authentication_methods_len; 629 630 /** 631 * Policies over the @e authentication_methods. 632 */ 633 struct ANASTASIS_ReduxPolicy *policies; 634 635 /** 636 * Length of the @e policies array. 637 */ 638 unsigned int policies_len; 639 640 /** 641 * Providers we will store the recovery document at. 642 */ 643 struct ANASTASIS_ReduxPolicyProvider *policy_providers; 644 645 /** 646 * Length of the @e policy_providers array. 647 */ 648 unsigned int policy_providers_len; 649 650 /** 651 * Per-currency total of what the backup will cost. 652 */ 653 struct TALER_Amount *upload_fees; 654 655 /** 656 * Length of the @e upload_fees array. 657 */ 658 unsigned int upload_fees_len; 659 660 /** 661 * Taler pay URIs the application must settle before we can continue 662 * uploading truths. 663 */ 664 char **payments; 665 666 /** 667 * Length of the @e payments array. 668 */ 669 unsigned int payments_len; 670 671 /** 672 * Payments the application must settle before we can upload the 673 * recovery document. 674 */ 675 struct ANASTASIS_ReduxPolicyPaymentRequest *policy_payment_requests; 676 677 /** 678 * Length of the @e policy_payment_requests array. 679 */ 680 unsigned int policy_payment_requests_len; 681 682 /** 683 * Where the recovery document ended up, per provider. 684 */ 685 struct ANASTASIS_ReduxSuccessDetail *success_details; 686 687 /** 688 * Length of the @e success_details array. 689 */ 690 unsigned int success_details_len; 691 692 /** 693 * The secret to back up. Deliberately untyped: its serialization is 694 * literally the secret that gets uploaded, so the reducer must never 695 * normalize it. NULL if not (yet) set. 696 */ 697 json_t *core_secret; 698 699 /** 700 * Name the user gave the secret, NULL if not set. 701 */ 702 char *secret_name; 703 704 /** 705 * When the backup should expire. 706 */ 707 struct GNUNET_TIME_Timestamp expiration; 708 709 /** 710 * True if @e expiration is set. 711 */ 712 bool have_expiration; 713 714 /** 715 * Arguments of the last "pay" action. 716 */ 717 struct ANASTASIS_ReduxPayArguments pay_arguments; 718 719 /** 720 * True if @e pay_arguments is set. 721 */ 722 bool have_pay_arguments; 723 724 /** 725 * True if the state has an @e authentication_methods field at all. 726 * As in #ANASTASIS_ReduxCommon, presence is tracked separately from 727 * the length because an empty array is meaningful. 728 */ 729 bool have_authentication_methods; 730 731 /** 732 * True if the state has a @e policies field at all. 733 */ 734 bool have_policies; 735 736 /** 737 * True if the state has a @e policy_providers field at all. 738 */ 739 bool have_policy_providers; 740 741 /** 742 * True if the state has an @e upload_fees field at all. 743 */ 744 bool have_upload_fees; 745 746 /** 747 * True if the state has a @e payments field at all. 748 */ 749 bool have_payments; 750 751 /** 752 * True if the state has a @e policy_payment_requests field at all. 753 */ 754 bool have_policy_payment_requests; 755 756 /** 757 * True if the state has a @e success_details field at all. 758 */ 759 bool have_success_details; 760 }; 761 762 763 /* ******************* Recovery-specific state *********************** */ 764 765 /** 766 * A challenge the user could solve to recover a key share. 767 */ 768 struct ANASTASIS_ReduxChallengeInfo 769 { 770 /** 771 * UUID of the truth behind this challenge. 772 */ 773 struct ANASTASIS_CRYPTO_TruthUUIDP uuid; 774 775 /** 776 * Type of the challenge, e.g. "question". 777 */ 778 char *type; 779 780 /** 781 * Instructions to show the user. 782 */ 783 char *instructions; 784 785 /** 786 * Answer the user gave to a secure question, NULL if none. Kept so 787 * that the answer survives the round-trip through the application 788 * when the provider demands payment before accepting it. 789 */ 790 char *answer; 791 792 /** 793 * Payment secret remembered from a payment request for this 794 * challenge; only valid if @e have_payment_secret. 795 */ 796 struct ANASTASIS_PaymentSecretP payment_secret; 797 798 /** 799 * True if @e payment_secret is set. 800 */ 801 bool have_payment_secret; 802 }; 803 804 805 /** 806 * A decryption policy: solving all of its challenges recovers the 807 * secret. 808 */ 809 struct ANASTASIS_ReduxRecoveryPolicy 810 { 811 /** 812 * UUIDs of the challenges in this policy; each refers to an entry of 813 * the recovery information's @e challenges array. 814 */ 815 struct ANASTASIS_CRYPTO_TruthUUIDP *uuids; 816 817 /** 818 * Length of the @e uuids array. 819 */ 820 unsigned int uuids_len; 821 }; 822 823 824 /** 825 * What we learned about the recovery document we are recovering from. 826 */ 827 struct ANASTASIS_ReduxRecoveryInfo 828 { 829 /** 830 * All challenges referenced by any policy. 831 */ 832 struct ANASTASIS_ReduxChallengeInfo *challenges; 833 834 /** 835 * Length of the @e challenges array. 836 */ 837 unsigned int challenges_len; 838 839 /** 840 * Alternative ways to recover the secret. 841 */ 842 struct ANASTASIS_ReduxRecoveryPolicy *policies; 843 844 /** 845 * Length of the @e policies array. 846 */ 847 unsigned int policies_len; 848 849 /** 850 * Name the user gave the secret, NULL if unknown. 851 */ 852 char *secret_name; 853 854 /** 855 * Provider we downloaded the recovery document from. 856 */ 857 struct ANASTASIS_ProviderUrl provider_url; 858 859 /** 860 * Version of the recovery document. 861 */ 862 uint32_t version; 863 }; 864 865 866 /** 867 * State of a challenge, as reported back to the application. 868 */ 869 enum ANASTASIS_ReduxFeedbackStatus 870 { 871 /** 872 * The TAN was written to a file (test setups only). 873 */ 874 ANASTASIS_RFS_CODE_IN_FILE = 0, 875 876 /** 877 * The TAN was sent to the user out-of-band. 878 */ 879 ANASTASIS_RFS_SEND_TO_ADDRESS = 1, 880 881 /** 882 * A Taler payment is required first. 883 */ 884 ANASTASIS_RFS_TALER_PAYMENT = 2, 885 886 /** 887 * The provider failed. 888 */ 889 ANASTASIS_RFS_SERVER_FAILURE = 3, 890 891 /** 892 * The provider does not know this truth. 893 */ 894 ANASTASIS_RFS_TRUTH_UNKNOWN = 4, 895 896 /** 897 * A wire transfer is required first. 898 */ 899 ANASTASIS_RFS_IBAN_INSTRUCTIONS = 5, 900 901 /** 902 * The challenge was solved. 903 */ 904 ANASTASIS_RFS_SOLVED = 6, 905 906 /** 907 * The answer the user gave was wrong. 908 */ 909 ANASTASIS_RFS_INCORRECT_ANSWER = 7, 910 911 /** 912 * Too many attempts. 913 */ 914 ANASTASIS_RFS_RATE_LIMIT_EXCEEDED = 8 915 }; 916 917 918 /** 919 * Feedback on one challenge. Serializes as one entry of the 920 * `challenge_feedback` object, keyed by @e uuid. 921 */ 922 struct ANASTASIS_ReduxFeedback 923 { 924 /** 925 * Challenge this feedback is about; the key this entry is stored 926 * under. 927 */ 928 struct ANASTASIS_CRYPTO_TruthUUIDP uuid; 929 930 /** 931 * Which variant of @e details is valid. 932 */ 933 enum ANASTASIS_ReduxFeedbackStatus status; 934 935 /** 936 * Human-readable, translated hint for the user. NULL for the 937 * variants that do not produce one. 938 */ 939 char *display_hint; 940 941 /** 942 * Variant-specific details. 943 */ 944 union 945 { 946 947 /** 948 * Details for #ANASTASIS_RFS_CODE_IN_FILE. 949 */ 950 struct 951 { 952 /** 953 * File the TAN was written to. 954 */ 955 char *filename; 956 } code_in_file; 957 958 /** 959 * Details for #ANASTASIS_RFS_SEND_TO_ADDRESS. 960 */ 961 struct 962 { 963 /** 964 * Redacted address the TAN went to, NULL if the provider did not 965 * say (because it had already sent the TAN earlier). 966 */ 967 char *address_hint; 968 } send_to_address; 969 970 /** 971 * Details for #ANASTASIS_RFS_TALER_PAYMENT. 972 */ 973 struct 974 { 975 /** 976 * URI the application must pay. 977 */ 978 char *taler_pay_uri; 979 980 /** 981 * Provider that wants to be paid. 982 */ 983 struct ANASTASIS_ProviderUrl provider; 984 985 /** 986 * Secret identifying the payment. 987 */ 988 struct ANASTASIS_PaymentSecretP payment_secret; 989 } taler_payment; 990 991 /** 992 * Details for #ANASTASIS_RFS_SERVER_FAILURE and 993 * #ANASTASIS_RFS_TRUTH_UNKNOWN. 994 */ 995 struct 996 { 997 /** 998 * Error code reported. 999 */ 1000 enum TALER_ErrorCode ec; 1001 1002 /** 1003 * HTTP status reported. 1004 */ 1005 uint32_t http_status; 1006 } server_failure; 1007 1008 /** 1009 * Details for #ANASTASIS_RFS_IBAN_INSTRUCTIONS. 1010 */ 1011 struct 1012 { 1013 /** 1014 * IBAN to wire the money to. 1015 */ 1016 char *target_iban; 1017 1018 /** 1019 * Name of the account holder. 1020 */ 1021 char *target_business_name; 1022 1023 /** 1024 * Subject to use for the wire transfer. 1025 */ 1026 char *wire_transfer_subject; 1027 1028 /** 1029 * Amount to wire. 1030 */ 1031 struct TALER_Amount amount; 1032 } iban_instructions; 1033 1034 /** 1035 * Details for #ANASTASIS_RFS_INCORRECT_ANSWER. 1036 */ 1037 struct 1038 { 1039 /** 1040 * Error code reported. 1041 */ 1042 enum TALER_ErrorCode ec; 1043 } incorrect_answer; 1044 1045 /** 1046 * Details for #ANASTASIS_RFS_RATE_LIMIT_EXCEEDED. 1047 */ 1048 struct 1049 { 1050 /** 1051 * Error code reported. 1052 */ 1053 enum TALER_ErrorCode ec; 1054 1055 /** 1056 * How many attempts are permitted per @e request_frequency. 1057 */ 1058 uint64_t request_limit; 1059 1060 /** 1061 * Length of the rate-limiting window. 1062 */ 1063 struct GNUNET_TIME_Relative request_frequency; 1064 } rate_limit_exceeded; 1065 1066 } details; 1067 }; 1068 1069 1070 /** 1071 * The `recovery` variant of the reducer state. 1072 */ 1073 struct ANASTASIS_ReduxRecovery 1074 { 1075 /** 1076 * Which step of the recovery process we are at. 1077 */ 1078 enum ANASTASIS_RecoveryState state; 1079 1080 /** 1081 * The recovery operation itself. This replaces what used to be the 1082 * `recovery_document` field: it is deserialized on parse (inert, no 1083 * network activity until ANASTASIS_recovery_resume() is called) and 1084 * serialized back on the way out. NULL before the recovery starts. 1085 */ 1086 struct ANASTASIS_Recovery *r; 1087 1088 /** 1089 * What we told the application about the recovery document, NULL 1090 * before the recovery starts. 1091 */ 1092 struct ANASTASIS_ReduxRecoveryInfo *ri; 1093 1094 /** 1095 * Feedback on challenges the user tried, keyed by truth UUID. 1096 */ 1097 struct ANASTASIS_ReduxFeedback *challenge_feedback; 1098 1099 /** 1100 * Length of the @e challenge_feedback array. 1101 */ 1102 unsigned int challenge_feedback_len; 1103 1104 /** 1105 * Challenge the user is currently working on; only valid if 1106 * @e have_selected_challenge. 1107 */ 1108 struct ANASTASIS_CRYPTO_TruthUUIDP selected_challenge; 1109 1110 /** 1111 * True if @e selected_challenge is set. 1112 */ 1113 bool have_selected_challenge; 1114 1115 /** 1116 * True if the state has a @e challenge_feedback field at all. 1117 */ 1118 bool have_challenge_feedback; 1119 1120 /** 1121 * The recovered secret. Deliberately untyped, see 1122 * ANASTASIS_ReduxBackup::core_secret. NULL until recovery succeeds. 1123 */ 1124 json_t *core_secret; 1125 }; 1126 1127 1128 /* ********************** Error state ******************************** */ 1129 1130 /** 1131 * The `error` variant of the reducer state. 1132 */ 1133 struct ANASTASIS_ReduxError 1134 { 1135 /** 1136 * The error that occurred. 1137 */ 1138 enum TALER_ErrorCode code; 1139 1140 /** 1141 * Hint derived from @e code, NULL if none. 1142 */ 1143 char *hint; 1144 1145 /** 1146 * Additional detail, NULL if none. 1147 */ 1148 char *detail; 1149 }; 1150 1151 1152 /* ********************** Top-level state **************************** */ 1153 1154 /** 1155 * Which variant of a #ANASTASIS_ReduxState is in use. 1156 */ 1157 enum ANASTASIS_ReduxType 1158 { 1159 /** 1160 * A backup is in progress; `reducer_type` is "backup". 1161 */ 1162 ANASTASIS_RT_BACKUP = 0, 1163 1164 /** 1165 * A recovery is in progress; `reducer_type` is "recovery". 1166 */ 1167 ANASTASIS_RT_RECOVERY = 1, 1168 1169 /** 1170 * Something went wrong; `reducer_type` is "error". 1171 */ 1172 ANASTASIS_RT_ERROR = 2 1173 }; 1174 1175 1176 /** 1177 * Fields shared by the backup and recovery variants. 1178 */ 1179 struct ANASTASIS_ReduxCommon 1180 { 1181 /** 1182 * Continents the user may pick from. 1183 */ 1184 struct ANASTASIS_ReduxContinent *continents; 1185 1186 /** 1187 * Length of the @e continents array. 1188 */ 1189 unsigned int continents_len; 1190 1191 /** 1192 * Countries on the selected continent. 1193 */ 1194 struct ANASTASIS_ReduxCountry *countries; 1195 1196 /** 1197 * Length of the @e countries array. 1198 */ 1199 unsigned int countries_len; 1200 1201 /** 1202 * Identity attributes we need from the user in the selected country. 1203 */ 1204 struct ANASTASIS_ReduxAttributeSpec *required_attributes; 1205 1206 /** 1207 * Length of the @e required_attributes array. 1208 */ 1209 unsigned int required_attributes_len; 1210 1211 /** 1212 * Providers we know about, keyed by URL. 1213 */ 1214 struct ANASTASIS_ReduxProvider *providers; 1215 1216 /** 1217 * Length of the @e providers array. 1218 */ 1219 unsigned int providers_len; 1220 1221 /** 1222 * The user's answers to @e required_attributes. Deliberately 1223 * untyped: this object is dumped with sorted keys and PoW-hashed to 1224 * derive the account key, so the reducer must not normalize it. NULL 1225 * if the user has not answered yet. 1226 */ 1227 json_t *identity_attributes; 1228 1229 /** 1230 * Continent the user selected, NULL if none. 1231 */ 1232 char *selected_continent; 1233 1234 /** 1235 * Country the user selected, NULL if none. 1236 */ 1237 char *selected_country; 1238 1239 /** 1240 * Currency the user would rather pay in, NULL if none was chosen. 1241 * Advisory: the orders carry every currency the provider accepts as a 1242 * choice, and the wallet is free to pick another one. Defaults to the 1243 * selected country's currency. 1244 */ 1245 char *preferred_currency; 1246 1247 /** 1248 * True if the state has a @e continents field at all. An array can 1249 * legitimately be present but empty, which is different from being 1250 * absent, so presence is tracked separately from the length. 1251 */ 1252 bool have_continents; 1253 1254 /** 1255 * True if the state has a @e countries field at all. 1256 */ 1257 bool have_countries; 1258 1259 /** 1260 * True if the state has a @e required_attributes field at all. 1261 */ 1262 bool have_required_attributes; 1263 1264 /** 1265 * True if the state has an @e authentication_providers field at all. 1266 */ 1267 bool have_providers; 1268 1269 /** 1270 * Currencies every provider used by this backup accepts, i.e. the 1271 * currencies in which the whole backup can be paid for with a single 1272 * choice of currency. May be empty, which is not an error: it means 1273 * the user will settle more than one order in more than one currency. 1274 */ 1275 char **currencies; 1276 1277 /** 1278 * Length of the @e currencies array. 1279 */ 1280 unsigned int currencies_len; 1281 1282 /** 1283 * True if the state has a @e currencies field at all. 1284 */ 1285 bool have_currencies; 1286 }; 1287 1288 1289 /** 1290 * A fully parsed reducer state. 1291 */ 1292 struct ANASTASIS_ReduxState 1293 { 1294 /** 1295 * Which variant of @e details is valid. 1296 */ 1297 enum ANASTASIS_ReduxType type; 1298 1299 /** 1300 * Fields common to the backup and recovery variants; unused when 1301 * @e type is #ANASTASIS_RT_ERROR. 1302 */ 1303 struct ANASTASIS_ReduxCommon common; 1304 1305 /** 1306 * Variant-specific state. 1307 */ 1308 union 1309 { 1310 1311 /** 1312 * Valid if @e type is #ANASTASIS_RT_BACKUP. 1313 */ 1314 struct ANASTASIS_ReduxBackup backup; 1315 1316 /** 1317 * Valid if @e type is #ANASTASIS_RT_RECOVERY. 1318 */ 1319 struct ANASTASIS_ReduxRecovery recovery; 1320 1321 /** 1322 * Valid if @e type is #ANASTASIS_RT_ERROR. 1323 */ 1324 struct ANASTASIS_ReduxError error; 1325 1326 } details; 1327 }; 1328 1329 1330 /* ******************* The three generic routines ******************** */ 1331 1332 /** 1333 * Parse @a json into a typed reducer state. This is the only routine 1334 * that reads the JSON encoding of a state. 1335 * 1336 * Parsing is strict: unknown fields, missing mandatory fields and 1337 * values of the wrong type all fail. 1338 * 1339 * @param json the state to parse 1340 * @param[out] ec set to the error that occurred, on failure 1341 * @param[out] detail set to a static string naming the offending field, 1342 * or NULL; never needs to be freed 1343 * @return NULL on failure, otherwise the parsed state, to be freed with 1344 * ANASTASIS_REDUX_state_free_() 1345 */ 1346 struct ANASTASIS_ReduxState * 1347 ANASTASIS_REDUX_state_parse_ (const json_t *json, 1348 enum TALER_ErrorCode *ec, 1349 const char **detail); 1350 1351 1352 /** 1353 * Serialize @a rs back into its JSON encoding. This is the only 1354 * routine that writes the JSON encoding of a state. 1355 * 1356 * @param rs the state to serialize 1357 * @return the JSON encoding, caller must json_decref() it; 1358 * NULL on failure 1359 */ 1360 json_t * 1361 ANASTASIS_REDUX_state_serialize_ (const struct ANASTASIS_ReduxState *rs); 1362 1363 1364 /** 1365 * Release all resources held by @a rs, including any live 1366 * `struct ANASTASIS_Recovery` and `struct ANASTASIS_Truth` handles. 1367 * 1368 * @param[in] rs the state to free, may be NULL 1369 */ 1370 void 1371 ANASTASIS_REDUX_state_free_ (struct ANASTASIS_ReduxState *rs); 1372 1373 1374 /** 1375 * Serialize @a rs, hand the result to @a cb, and free @a rs. This is 1376 * how every action returns its result: it guarantees that the JSON 1377 * encoding is produced in exactly one place and that the state is not 1378 * leaked on any path. 1379 * 1380 * @param[in] rs state to return and free 1381 * @param cb callback to invoke 1382 * @param cb_cls closure for @a cb 1383 * @param ec error code to report alongside the state 1384 */ 1385 void 1386 ANASTASIS_REDUX_return_ (struct ANASTASIS_ReduxState *rs, 1387 ANASTASIS_ActionCallback cb, 1388 void *cb_cls, 1389 enum TALER_ErrorCode ec); 1390 1391 1392 /** 1393 * Report @a ec to @a cb and free @a rs. The counterpart of 1394 * #ANASTASIS_REDUX_return_ for the failure path: the reducer replies 1395 * with a freshly built `error` state, so whatever @a rs held is 1396 * discarded rather than serialized. 1397 * 1398 * @param[in] rs state to free, may be NULL 1399 * @param cb callback to invoke 1400 * @param cb_cls closure for @a cb 1401 * @param ec error to report 1402 * @param detail human-readable detail, may be NULL 1403 */ 1404 void 1405 ANASTASIS_REDUX_fail_ (struct ANASTASIS_ReduxState *rs, 1406 ANASTASIS_ActionCallback cb, 1407 void *cb_cls, 1408 enum TALER_ErrorCode ec, 1409 const char *detail); 1410 1411 1412 /* #ANASTASIS_REDUX_StateCallback, the internal counterpart of 1413 #ANASTASIS_ActionCallback, is declared in `anastasis_api_redux.h`. */ 1414 1415 1416 /* ************************ Small helpers **************************** */ 1417 1418 /** 1419 * Find the provider with the given @a url in @a common. 1420 * 1421 * @param common state to search 1422 * @param url provider URL to look for 1423 * @return NULL if not found 1424 */ 1425 struct ANASTASIS_ReduxProvider * 1426 ANASTASIS_REDUX_provider_find_ (const struct ANASTASIS_ReduxCommon *common, 1427 const char *url); 1428 1429 1430 /** 1431 * Drop all providers from @a common, freeing them. Used when the set 1432 * of applicable providers changes wholesale, e.g. because the user 1433 * picked a different country. 1434 * 1435 * @param[in,out] common state to clear 1436 */ 1437 void 1438 ANASTASIS_REDUX_providers_clear_ (struct ANASTASIS_ReduxCommon *common); 1439 1440 1441 /** 1442 * Free the contents of @a cfg and zero it. 1443 * 1444 * @param[in,out] cfg provider configuration to clear 1445 */ 1446 void 1447 ANASTASIS_REDUX_provider_config_clear_ ( 1448 struct ANASTASIS_ReduxProviderConfig *cfg); 1449 1450 1451 /** 1452 * Drop all continents from @a common, freeing them. 1453 * 1454 * @param[in,out] common state to clear 1455 */ 1456 void 1457 ANASTASIS_REDUX_continents_clear_ (struct ANASTASIS_ReduxCommon *common); 1458 1459 1460 /** 1461 * Drop all countries from @a common, freeing them. 1462 * 1463 * @param[in,out] common state to clear 1464 */ 1465 void 1466 ANASTASIS_REDUX_countries_clear_ (struct ANASTASIS_ReduxCommon *common); 1467 1468 1469 /** 1470 * Drop all required attributes from @a common, freeing them. 1471 * 1472 * @param[in,out] common state to clear 1473 */ 1474 void 1475 ANASTASIS_REDUX_required_attributes_clear_ ( 1476 struct ANASTASIS_ReduxCommon *common); 1477 1478 1479 /* ****************** Importing from resource files ****************** */ 1480 1481 /* 1482 * The reducer's resource files (`redux.countries.json`, `redux.$CC.json`) 1483 * and the `add_provider` action supply data in exactly the JSON encoding 1484 * the parser already understands. Rather than have a second, subtly 1485 * different reader for them, the relevant parser fragments are exposed 1486 * here. Each replaces whatever the state held before. 1487 */ 1488 1489 /** 1490 * Replace the countries of @a common with those in @a arr. 1491 * 1492 * @param[in,out] common state to update 1493 * @param arr array of countries in the state's JSON encoding 1494 * @param[out] detail set to the offending field on failure 1495 * @return #GNUNET_OK on success 1496 */ 1497 enum GNUNET_GenericReturnValue 1498 ANASTASIS_REDUX_countries_set_ (struct ANASTASIS_ReduxCommon *common, 1499 const json_t *arr, 1500 const char **detail); 1501 1502 1503 /** 1504 * Replace the required attributes of @a common with those in @a arr. 1505 * 1506 * @param[in,out] common state to update 1507 * @param arr array of attribute specifications in the state's JSON 1508 * encoding 1509 * @param[out] detail set to the offending field on failure 1510 * @return #GNUNET_OK on success 1511 */ 1512 enum GNUNET_GenericReturnValue 1513 ANASTASIS_REDUX_required_attributes_set_ (struct ANASTASIS_ReduxCommon *common, 1514 const json_t *arr, 1515 const char **detail); 1516 1517 1518 /** 1519 * Replace the entry for provider @a url in @a common with @a val, 1520 * adding the provider if it was not known yet. 1521 * 1522 * @param[in,out] common state to update 1523 * @param url provider the entry is about 1524 * @param val the entry in the state's JSON encoding 1525 * @param[out] detail set to the offending field on failure 1526 * @return #GNUNET_OK on success 1527 */ 1528 enum GNUNET_GenericReturnValue 1529 ANASTASIS_REDUX_provider_set_ (struct ANASTASIS_ReduxCommon *common, 1530 const char *url, 1531 const json_t *val, 1532 const char **detail); 1533 1534 1535 /** 1536 * Find, or create, the provider with the given @a url in @a common. 1537 * 1538 * @param[in,out] common state to search and possibly grow 1539 * @param url provider URL to look for 1540 * @return the existing or newly added (and #ANASTASIS_RPS_NOT_CONTACTED) 1541 * provider entry 1542 */ 1543 struct ANASTASIS_ReduxProvider * 1544 ANASTASIS_REDUX_provider_get_ (struct ANASTASIS_ReduxCommon *common, 1545 const char *url); 1546 1547 1548 /** 1549 * Find the feedback for challenge @a uuid in @a rr. 1550 * 1551 * @param rr recovery state to search 1552 * @param uuid challenge to look for 1553 * @return NULL if not found 1554 */ 1555 struct ANASTASIS_ReduxFeedback * 1556 ANASTASIS_REDUX_feedback_find_ (const struct ANASTASIS_ReduxRecovery *rr, 1557 const struct ANASTASIS_CRYPTO_TruthUUIDP *uuid); 1558 1559 1560 /** 1561 * Find, or create, the feedback entry for challenge @a uuid in @a rr. 1562 * An existing entry is reset (its variant-specific fields freed) so 1563 * that the caller can fill in a fresh variant. 1564 * 1565 * @param[in,out] rr recovery state to search and possibly grow 1566 * @param uuid challenge to look for 1567 * @return the entry to fill in 1568 */ 1569 struct ANASTASIS_ReduxFeedback * 1570 ANASTASIS_REDUX_feedback_get_ (struct ANASTASIS_ReduxRecovery *rr, 1571 const struct ANASTASIS_CRYPTO_TruthUUIDP *uuid); 1572 1573 1574 /** 1575 * Free the variant-specific contents of @a fb (including the display 1576 * hint), but not @a fb itself, and zero them. Used both when freeing 1577 * a state and when overwriting a feedback entry with a new variant. 1578 * 1579 * @param[in,out] fb feedback to reset 1580 */ 1581 void 1582 ANASTASIS_REDUX_feedback_clear_ (struct ANASTASIS_ReduxFeedback *fb); 1583 1584 1585 /** 1586 * Find the challenge with the given @a uuid in the recovery 1587 * information of @a rr. 1588 * 1589 * @param rr recovery state to search 1590 * @param uuid challenge to look for 1591 * @return NULL if not found 1592 */ 1593 struct ANASTASIS_ReduxChallengeInfo * 1594 ANASTASIS_REDUX_challenge_find_ (const struct ANASTASIS_ReduxRecovery *rr, 1595 const struct 1596 ANASTASIS_CRYPTO_TruthUUIDP *uuid); 1597 1598 1599 /** 1600 * Free the contents of the policy @a p and zero it. 1601 * 1602 * @param[in,out] p policy to clear 1603 */ 1604 void 1605 ANASTASIS_REDUX_policy_clear_ (struct ANASTASIS_ReduxPolicy *p); 1606 1607 1608 /** 1609 * Drop all policies from @a backup, freeing them. 1610 * 1611 * @param[in,out] backup state to clear 1612 */ 1613 void 1614 ANASTASIS_REDUX_policies_clear_ (struct ANASTASIS_ReduxBackup *backup); 1615 1616 1617 /** 1618 * Drop all policy providers from @a backup, freeing them. 1619 * 1620 * @param[in,out] backup state to clear 1621 */ 1622 void 1623 ANASTASIS_REDUX_policy_providers_clear_ (struct ANASTASIS_ReduxBackup *backup); 1624 1625 1626 /** 1627 * Drop the pending truth payments from @a backup, freeing them, and 1628 * mark the field as absent. 1629 * 1630 * @param[in,out] backup state to clear 1631 */ 1632 void 1633 ANASTASIS_REDUX_payments_clear_ (struct ANASTASIS_ReduxBackup *backup); 1634 1635 1636 /** 1637 * Drop the pending policy payments from @a backup, freeing them, and 1638 * mark the field as absent. 1639 * 1640 * @param[in,out] backup state to clear 1641 */ 1642 void 1643 ANASTASIS_REDUX_policy_payment_requests_clear_ ( 1644 struct ANASTASIS_ReduxBackup *backup); 1645 1646 1647 /** 1648 * Free the recovery information @a ri. 1649 * 1650 * @param[in] ri recovery information to free, may be NULL 1651 */ 1652 void 1653 ANASTASIS_REDUX_recovery_info_free_ (struct ANASTASIS_ReduxRecoveryInfo *ri); 1654 1655 1656 /** 1657 * Free the contents of @a pu and set it to NULL. 1658 * 1659 * @param[in,out] pu provider URL to clear 1660 */ 1661 void 1662 ANASTASIS_REDUX_provider_url_clear_ (struct ANASTASIS_ProviderUrl *pu); 1663 1664 1665 /** 1666 * Set @a pu to a copy of @a url, freeing any previous value. 1667 * 1668 * @param[in,out] pu provider URL to set 1669 * @param url the URL to copy 1670 */ 1671 void 1672 ANASTASIS_REDUX_provider_url_set_ (struct ANASTASIS_ProviderUrl *pu, 1673 const char *url); 1674 1675 1676 #endif 1677 1678 /* end of anastasis_api_redux_state.h */