diff options
author | Christian Grothoff <christian@grothoff.org> | 2021-07-30 10:38:27 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2021-07-30 10:38:27 +0200 |
commit | 7e669bcf6b6336ec429da949bcb4aa456971dba2 (patch) | |
tree | d19912f950d1cac1c38b857b7d5bdaba2289544e /src/include | |
download | anastasis-7e669bcf6b6336ec429da949bcb4aa456971dba2.tar.gz anastasis-7e669bcf6b6336ec429da949bcb4aa456971dba2.tar.bz2 anastasis-7e669bcf6b6336ec429da949bcb4aa456971dba2.zip |
folding history in preparation of GNU Anastasis v0.0.0 release
Diffstat (limited to 'src/include')
-rw-r--r-- | src/include/Makefile.am | 15 | ||||
-rw-r--r-- | src/include/anastasis.h | 986 | ||||
-rw-r--r-- | src/include/anastasis_authorization_lib.h | 52 | ||||
-rw-r--r-- | src/include/anastasis_authorization_plugin.h | 183 | ||||
-rw-r--r-- | src/include/anastasis_crypto_lib.h | 533 | ||||
-rw-r--r-- | src/include/anastasis_database_lib.h | 49 | ||||
-rw-r--r-- | src/include/anastasis_database_plugin.h | 655 | ||||
-rw-r--r-- | src/include/anastasis_json.h | 410 | ||||
-rw-r--r-- | src/include/anastasis_redux.h | 127 | ||||
-rw-r--r-- | src/include/anastasis_service.h | 703 | ||||
-rw-r--r-- | src/include/anastasis_testing_lib.h | 884 | ||||
-rw-r--r-- | src/include/anastasis_util_lib.h | 82 | ||||
-rw-r--r-- | src/include/gettext.h | 71 | ||||
-rw-r--r-- | src/include/platform.h | 60 |
14 files changed, 4810 insertions, 0 deletions
diff --git a/src/include/Makefile.am b/src/include/Makefile.am new file mode 100644 index 0000000..f9f6548 --- /dev/null +++ b/src/include/Makefile.am @@ -0,0 +1,15 @@ +# This Makefile.am is in the public domain +anastasisincludedir = $(includedir)/anastasis + +anastasisinclude_HEADERS = \ + platform.h gettext.h \ + anastasis_database_plugin.h \ + anastasis_service.h \ + anastasis_error_codes.h \ + anastasis_database_lib.h \ + anastasis_util_lib.h \ + anastasis_crypto_lib.h \ + anastasis_redux.h \ + anastasis_authorization_plugin.h \ + anastasis_authorization_lib.h \ + anastasis.h diff --git a/src/include/anastasis.h b/src/include/anastasis.h new file mode 100644 index 0000000..1591106 --- /dev/null +++ b/src/include/anastasis.h @@ -0,0 +1,986 @@ +/* + This file is part of Anastasis + Copyright (C) 2020, 2021 Taler Systems SA + + Anastasis is free software; you can redistribute it and/or modify it under the + terms of the GNU Lesser General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/> +*/ +/** + * @file include/anastasis.h + * @brief anastasis high-level client api + * @author Christian Grothoff + * @author Dominik Meister + * @author Dennis Neufeld + */ +#ifndef ANASTASIS_H +#define ANASTASIS_H + +#include "anastasis_service.h" +#include <taler/taler_json_lib.h> +#include <gnunet/gnunet_util_lib.h> +#include <stdbool.h> + + +/* ********************* Recovery api *********************** */ + +/** + * Defines the instructions for a challenge, what does the user have + * to do to fulfill the challenge. Also defines the method and other + * information for the challenge like a link for the video indent or a + * information to which address an e-mail was sent. + */ +struct ANASTASIS_Challenge; + + +/** + * Defines the instructions for a challenge, what does the user have + * to do to fulfill the challenge. Also defines the method and other + * information for the challenge like a link for the video indent or a + * information to which address an e-mail was sent. + */ +struct ANASTASIS_ChallengeDetails +{ + + /** + * UUID which identifies this challenge + */ + struct ANASTASIS_CRYPTO_TruthUUIDP uuid; + + /** + * Which type is this challenge (E-Mail, Security Question, SMS...) + */ + const char *type; + + /** + * Defines the base URL of the Anastasis provider used for the challenge. + */ + const char *provider_url; + + /** + * Instructions for solving the challenge (generic, set client-side + * when challenge was established). + */ + const char *instructions; + + /** + * true if challenged was already solved, else false. + */ + bool solved; + +}; + + +/** + * Return public details about a challenge. + * + * @param challenge the challenge to inspect + * @return public details about the challenge + */ +const struct ANASTASIS_ChallengeDetails * +ANASTASIS_challenge_get_details (struct ANASTASIS_Challenge *challenge); + + +/** + * Possible outcomes of trying to start a challenge operation. + */ +enum ANASTASIS_ChallengeStatus +{ + + /** + * The challenge has been solved. + */ + ANASTASIS_CHALLENGE_STATUS_SOLVED, + + /** + * Instructions for how to solve the challenge are provided. Also + * used if the answer we provided was wrong (or if no answer was + * provided, but one is needed). + */ + ANASTASIS_CHALLENGE_STATUS_INSTRUCTIONS, + + /** + * A redirection URL needed to solve the challenge is provided. Also + * used if the answer we provided was wrong (or if no answer was + * provided, but one is needed). + */ + ANASTASIS_CHALLENGE_STATUS_REDIRECT_FOR_AUTHENTICATION, + + /** + * Payment is required before the challenge can be answered. + */ + ANASTASIS_CHALLENGE_STATUS_PAYMENT_REQUIRED, + + /** + * We encountered an error talking to the Anastasis service. + */ + ANASTASIS_CHALLENGE_STATUS_SERVER_FAILURE, + + /** + * The server does not know this truth. + */ + ANASTASIS_CHALLENGE_STATUS_TRUTH_UNKNOWN, + + /** + * The rate limit for solving the challenge was exceeded. + */ + ANASTASIS_CHALLENGE_STATUS_RATE_LIMIT_EXCEEDED + +}; + + +/** + * Response from an #ANASTASIS_challenge_start() operation. + */ +struct ANASTASIS_ChallengeStartResponse +{ + /** + * What is our status on satisfying this challenge. Determines @e details. + */ + enum ANASTASIS_ChallengeStatus cs; + + /** + * Which challenge is this about? + */ + struct ANASTASIS_Challenge *challenge; + + /** + * Details depending on @e cs + */ + union + { + + /** + * Challenge details provided if + * @e cs is #ANASTASIS_CHALLENGE_STATUS_INSTRUCTIONS. + */ + struct + { + + /** + * Response with server-side instructions for the user. + */ + const void *body; + + /** + * Mime type of the data in @e body. + */ + const char *content_type; + + /** + * Number of bytes in @e body + */ + size_t body_size; + + /** + * HTTP status returned by the server. #MHD_HTTP_ALREADY_REPORTED + * if the server did already send the challenge to the user, + * #MHD_HTTP_FORBIDDEN if the answer was wrong (or missing). + */ + unsigned int http_status; + } open_challenge; + + + /** + * Response with URL to redirect the user to, if + * @e cs is #ANASTASIS_CHALLENGE_STATUS_REDIRECT_FOR_AUTHENTICATION. + */ + const char *redirect_url; + + /** + * Response with instructions for how to pay, if + * @e cs is #ANASTASIS_CHALLENGE_STATUS_PAYMENT_REQUIRED. + */ + struct + { + + /** + * "taler://pay" URI with details how to pay for the challenge. + */ + const char *taler_pay_uri; + + /** + * Payment secret from @e taler_pay_uri. + */ + struct ANASTASIS_PaymentSecretP payment_secret; + + } payment_required; + + + /** + * Response with details about a server-side failure, if + * @e cs is #ANASTASIS_CHALLENGE_STATUS_SERVER_FAILURE. + */ + struct + { + + /** + * HTTP status returned by the server. + */ + unsigned int http_status; + + /** + * Taler-specific error code. + */ + enum TALER_ErrorCode ec; + + } server_failure; + + } details; +}; + + +/** + * Defines a callback for the response status for a challenge start + * operation. + * + * @param cls closure + * @param csr response details + */ +typedef void +(*ANASTASIS_AnswerFeedback)( + void *cls, + const struct ANASTASIS_ChallengeStartResponse *csr); + + +/** + * User starts a challenge which reponds out of bounds (E-Mail, SMS, + * Postal..) If the challenge is zero cost, the challenge + * instructions will be sent to the client. If the challenge needs + * payment a payment link is sent to the client. After payment the + * challenge start method has to be called again. + * + * @param c reference to the escrow challenge which is started + * @param psp payment secret, NULL if no payment was yet made + * @param timeout how long to wait for payment + * @param hashed_answer answer to the challenge, NULL if we have none yet + * @param af reference to the answerfeedback which is passed back to the user + * @param af_cls closure for @a af + * @return #GNUNET_OK if the challenge was successfully started + */ +int +ANASTASIS_challenge_start (struct ANASTASIS_Challenge *c, + const struct ANASTASIS_PaymentSecretP *psp, + struct GNUNET_TIME_Relative timeout, + const struct GNUNET_HashCode *hashed_answer, + ANASTASIS_AnswerFeedback af, + void *af_cls); + + +/** + * Challenge answer for a security question. Is referenced to + * a challenge and sends back an AnswerFeedback. Convenience + * wrapper around #ANASTASIS_challenge_start that hashes @a answer + * for security questions. + * + * @param c reference to the challenge which is answered + * @param psp information about payment made for the recovery + * @param timeout how long to wait for payment + * @param answer user input instruction defines which input is needed + * @param af reference to the answerfeedback which is passed back to the user + * @param af_cls closure for @a af + * @return #GNUNET_OK on success + */ +int +ANASTASIS_challenge_answer (struct ANASTASIS_Challenge *c, + const struct ANASTASIS_PaymentSecretP *psp, + struct GNUNET_TIME_Relative timeout, + const char *answer, + ANASTASIS_AnswerFeedback af, + void *af_cls); + + +/** + * Challenge answer from the user like input SMS TAN or e-mail wpin. Is + * referenced to a challenge and sends back an AnswerFeedback. + * Convenience wrapper around #ANASTASIS_challenge_start that hashes + * numeric (unsalted) @a answer. Variant for numeric answers. + * + * @param c reference to the challenge which is answered + * @param psp information about payment made for the recovery + * @param timeout how long to wait for payment + * @param answer user input instruction defines which input is needed + * @param af reference to the answerfeedback which is passed back to the user + * @param af_cls closure for @a af + * @return #GNUNET_OK on success + */ +int +ANASTASIS_challenge_answer2 (struct ANASTASIS_Challenge *c, + const struct ANASTASIS_PaymentSecretP *psp, + struct GNUNET_TIME_Relative timeout, + uint64_t answer, + ANASTASIS_AnswerFeedback af, + void *af_cls); + + +/** + * Abort answering challenge. + * + * @param c reference to the escrow challenge which was started + */ +void +ANASTASIS_challenge_abort (struct ANASTASIS_Challenge *c); + + +/** + * Defines a Decryption Policy with multiple escrow methods + */ +struct ANASTASIS_DecryptionPolicy +{ + /** + * Array of challenges needed to solve for this decryption policy. + */ + struct ANASTASIS_Challenge **challenges; + + /** + * Length of the @a challenges in this policy. + */ + unsigned int challenges_length; + +}; + + +/** + * Defines the recovery information (possible policies and version of the recovery document) + */ +struct ANASTASIS_RecoveryInformation +{ + + /** + * Array of @e dps_len policies that would allow recovery of the core secret. + */ + struct ANASTASIS_DecryptionPolicy **dps; + + /** + * Array of all @e cs_len challenges to be solved (for any of the policies). + */ + struct ANASTASIS_Challenge **cs; + + /** + * Name of the secret being recovered, possibly NULL. + */ + const char *secret_name; + + /** + * Length of the @e dps array. + */ + unsigned int dps_len; + + /** + * Length of the @e cs array. + */ + unsigned int cs_len; + + /** + * Actual recovery document version obtained. + */ + unsigned int version; +}; + + +/** + * Callback which passes back the recovery document and its possible + * policies. Also passes back the version of the document for the user + * to check. + * + * @param cls closure for the callback + * @param ri recovery information struct which contains the policies + */ +typedef void +(*ANASTASIS_PolicyCallback)(void *cls, + const struct ANASTASIS_RecoveryInformation *ri); + + +/** + * Possible outcomes of a recovery process. + */ +enum ANASTASIS_RecoveryStatus +{ + + /** + * Recovery succeeded. + */ + ANASTASIS_RS_SUCCESS = 0, + + /** + * The HTTP download of the policy failed. + */ + ANASTASIS_RS_POLICY_DOWNLOAD_FAILED, + + /** + * We did not get a valid policy document. + */ + ANASTASIS_RS_POLICY_DOWNLOAD_NO_POLICY, + + /** + * The decompressed policy document was too big for available memory. + */ + ANASTASIS_RS_POLICY_DOWNLOAD_TOO_BIG, + + /** + * The decrypted policy document was not compressed. + */ + ANASTASIS_RS_POLICY_DOWNLOAD_INVALID_COMPRESSION, + + /** + * The decompressed policy document was not in JSON. + */ + ANASTASIS_RS_POLICY_DOWNLOAD_NO_JSON, + + /** + * The decompressed policy document was in malformed JSON. + */ + ANASTASIS_RS_POLICY_MALFORMED_JSON, + + /** + * The Anastasis server reported a transient error. + */ + ANASTASIS_RS_POLICY_SERVER_ERROR, + + /** + * The Anastasis server no longer has a policy (likely expired). + */ + ANASTASIS_RS_POLICY_GONE, + + /** + * The Anastasis server reported that the account is unknown. + */ + ANASTASIS_RS_POLICY_UNKNOWN +}; + + +/** + * This function is called whenever the recovery process ends. + * On success, the secret is returned in @a secret. + * + * @param cls closure + * @param ec error code + * @param secret contains the core secret which is passed to the user + * @param secret_size defines the size of the core secret + */ +typedef void +(*ANASTASIS_CoreSecretCallback)(void *cls, + enum ANASTASIS_RecoveryStatus rc, + const void *secret, + size_t secret_size); + + +/** + * stores provider URIs, identity key material, decrypted recovery document (internally!) + */ +struct ANASTASIS_Recovery; + + +/** + * Starts the recovery process by opening callbacks for the coresecret and a policy callback. A list of + * providers is checked for policies and passed back to the client. + * + * @param ctx context for making HTTP requests + * @param id_data contains the users identity, (user account on providers) + * @param version defines the version which will be downloaded NULL for latest version + * @param anastasis_provider_url NULL terminated list of possible provider urls + * @param provider_salt the server salt + * @param pc opens the policy call back which holds the downloaded version and the policies + * @param pc_cls closure for callback + * @param csc core secret callback is opened, with this the core secert is passed to the client after the authentication + * @param csc_cls handle for the callback + * @return recovery operation handle + */ +struct ANASTASIS_Recovery * +ANASTASIS_recovery_begin ( + struct GNUNET_CURL_Context *ctx, + const json_t *id_data, + unsigned int version, + const char *anastasis_provider_url, + const struct ANASTASIS_CRYPTO_ProviderSaltP *provider_salt, + ANASTASIS_PolicyCallback pc, + void *pc_cls, + ANASTASIS_CoreSecretCallback csc, + void *csc_cls); + + +/** + * Serialize recovery operation state and returning it. + * The recovery MAY still continue, applications should call + * #ANASTASIS_recovery_abort() to truly end the recovery. + * + * @param r recovery operation to suspend. + * @return JSON serialized state of @a r + */ +json_t * +ANASTASIS_recovery_serialize (const struct ANASTASIS_Recovery *r); + + +/** + * Deserialize recovery operation. + * + * @param ctx context for making HTTP requests + * @param input result from #ANASTASIS_recovery_serialize() + * @param pc opens the policy call back which holds the downloaded version and the policies + * @param pc_cls closure for callback + * @param csc core secret callback is opened, with this the core secert is passed to the client after the authentication + * @param csc_cls handle for the callback + * @return recovery operation handle + */ +struct ANASTASIS_Recovery * +ANASTASIS_recovery_deserialize (struct GNUNET_CURL_Context *ctx, + const json_t *input, + ANASTASIS_PolicyCallback pc, + void *pc_cls, + ANASTASIS_CoreSecretCallback csc, + void *csc_cls); + + +/** + * Cancels the recovery process + * + * @param r handle to the recovery struct + */ +void +ANASTASIS_recovery_abort (struct ANASTASIS_Recovery *r); + + +/* ************************* Backup API ***************************** */ + + +/** + * Represents a truth object, which is a key share and the respective + * challenge to be solved with an Anastasis provider to recover the + * key share. + */ +struct ANASTASIS_Truth; + + +/** + * Extracts truth data from JSON. + * + * @param json JSON encoding to decode; truth returned ONLY valid as long + * as the JSON remains valid (do not decref until the truth + * is truly finished) + * @return decoded truth object, NULL on error + */ +struct ANASTASIS_Truth * +ANASTASIS_truth_from_json (const json_t *json); + + +/** + * Returns JSON-encoded truth data. + * Creates a policy with a set of truth's. Creates the policy key + * with the different key shares from the @a truths. The policy key + * will then be used to encrypt/decrypt the escrow master key. + * + * @param t object to return JSON encoding for + * @return JSON encoding of @a t + */ +json_t * +ANASTASIS_truth_to_json (const struct ANASTASIS_Truth *t); + + +/** + * Handle for the operation to establish a truth object by sharing + * an encrypted key share with an Anastasis provider. + */ +struct ANASTASIS_TruthUpload; + + +/** + * Upload result information. The resulting truth object can be used + * to create policies. If payment is required, the @a taler_pay_url + * is returned and the operation must be retried after payment. + * Callee MUST free @a t using ANASTASIS_truth_free(). + * + * @param cls closure for callback + * @param t truth object to create policies, NULL on failure + * @param ud upload details, useful to continue in case of errors, NULL on success + */ +typedef void +(*ANASTASIS_TruthCallback)(void *cls, + struct ANASTASIS_Truth *t, + const struct ANASTASIS_UploadDetails *ud); + + +/** + * Uploads truth data to an escrow provider. The resulting truth object + * is returned via the @a tc function. If payment is required, it is + * requested via the @a tcp callback. + * + * @param ctx the CURL context used to connect to the backend + * @param user_id user identifier derived from user data and backend salt + * @param type defines the type of the challenge (secure question, sms, email) + * @param instructions depending on @a type! usually only for security question/answer! + * @param mime_type format of the challenge + * @param provider_salt the providers salt + * @param truth_data contains the truth for this challenge i.e. phone number, email address + * @param truth_data_size size of the @a truth_data + * @param payment_years_requested for how many years would the client like the service to store the truth? + * @param pay_timeout how long to wait for payment + * @param tc opens the truth callback which contains the status of the upload + * @param tc_cls closure for the @a tc callback + */ +struct ANASTASIS_TruthUpload * +ANASTASIS_truth_upload ( + struct GNUNET_CURL_Context *ctx, + const struct ANASTASIS_CRYPTO_UserIdentifierP *user_id, + const char *provider_url, + const char *type, + const char *instructions, + const char *mime_type, + const struct ANASTASIS_CRYPTO_ProviderSaltP *provider_salt, + const void *truth_data, + size_t truth_data_size, + uint32_t payment_years_requested, + struct GNUNET_TIME_Relative pay_timeout, + ANASTASIS_TruthCallback tc, + void *tc_cls); + + +/** + * Retries upload of truth data to an escrow provider. The resulting + * truth object is returned via the @a tc function. If payment is + * required, it is requested via the @a tcp callback. + * + * @param ctx the CURL context used to connect to the backend + * @param user_id user identifier derived from user data and backend salt + * @param type defines the type of the challenge (secure question, sms, email) + * @param instructions depending on @a type! usually only for security question/answer! + * @param mime_type format of the challenge + * @param provider_salt the providers salt + * @param truth_data contains the truth for this challenge i.e. phone number, email address + * @param truth_data_size size of the @a truth_data + * @param payment_years_requested for how many years would the client like the service to store the truth? + * @param pay_timeout how long to wait for payment + * @param nonce nonce to use for symmetric encryption + * @param uuid truth UUID to use + * @param salt salt to use to hash security questions + * @param truth_key symmetric encryption key to use to encrypt @a truth_data + * @param key_share share of the overall key to store in this truth object + * @param tc opens the truth callback which contains the status of the upload + * @param tc_cls closure for the @a tc callback + */ +struct ANASTASIS_TruthUpload * +ANASTASIS_truth_upload2 ( + struct GNUNET_CURL_Context *ctx, + const struct ANASTASIS_CRYPTO_UserIdentifierP *user_id, + const char *provider_url, + const char *type, + const char *instructions, + const char *mime_type, + const struct ANASTASIS_CRYPTO_ProviderSaltP *provider_salt, + const void *truth_data, + size_t truth_data_size, + uint32_t payment_years_requested, + struct GNUNET_TIME_Relative pay_timeout, + const struct ANASTASIS_CRYPTO_NonceP *nonce, + const struct ANASTASIS_CRYPTO_TruthUUIDP *uuid, + const struct ANASTASIS_CRYPTO_QuestionSaltP *salt, + const struct ANASTASIS_CRYPTO_TruthKeyP *truth_key, + const struct ANASTASIS_CRYPTO_KeyShareP *key_share, + ANASTASIS_TruthCallback tc, + void *tc_cls); + + +/** + * Retries upload of truth data to an escrow provider using an + * existing truth object. If payment is required, it is requested via + * the @a tc callback. + * + * @param ctx the CURL context used to connect to the backend + * @param user_id user identifier derived from user data and backend salt + * @param[in] t truth details, reference is consumed + * @param truth_data contains the truth for this challenge i.e. phone number, email address + * @param truth_data_size size of the @a truth_data + * @param payment_years_requested for how many years would the client like the service to store the truth? + * @param pay_timeout how long to wait for payment + * @param tc opens the truth callback which contains the status of the upload + * @param tc_cls closure for the @a tc callback + */ +struct ANASTASIS_TruthUpload * +ANASTASIS_truth_upload3 (struct GNUNET_CURL_Context *ctx, + const struct ANASTASIS_CRYPTO_UserIdentifierP *user_id, + struct ANASTASIS_Truth *t, + const void *truth_data, + size_t truth_data_size, + uint32_t payment_years_requested, + struct GNUNET_TIME_Relative pay_timeout, + ANASTASIS_TruthCallback tc, + void *tc_cls); + + +/** + * Cancels a truth upload process. + * + * @param tu handle for the upload + */ +void +ANASTASIS_truth_upload_cancel (struct ANASTASIS_TruthUpload *tu); + + +/** + * Free's the truth object which was returned to a #ANASTASIS_TruthCallback. + * + * @param t object to clean up + */ +void +ANASTASIS_truth_free (struct ANASTASIS_Truth *t); + + +/** + * Policy object, representing a set of truths (and thus challenges + * to satisfy) to recover a secret. + */ +struct ANASTASIS_Policy; + + +/** + * Creates a policy with a set of truth's. Creates the policy key + * with the different key shares from the @a truths. The policy key + * will then be used to encrypt/decrypt the escrow master key. + * + * @param truths array of truths which are stored on different providers + * @param truths_len length of the @a truths array + */ +struct ANASTASIS_Policy * +ANASTASIS_policy_create (const struct ANASTASIS_Truth *truths[], + unsigned int truths_len); + + +/** + * Destroys a policy object. + * + * @param p handle for the policy to destroy + */ +void +ANASTASIS_policy_destroy (struct ANASTASIS_Policy *p); + + +/** + * Information about a provider requesting payment for storing a policy. + */ +struct ANASTASIS_SharePaymentRequest +{ + /** + * Payment request URL. + */ + const char *payment_request_url; + + /** + * Base URL of the provider requesting payment. + */ + const char *provider_url; + + /** + * The payment secret (aka order ID) extracted from the @e payment_request_url. + */ + struct ANASTASIS_PaymentSecretP payment_secret; +}; + + +/** + * Result of uploading share data. + */ +enum ANASTASIS_ShareStatus +{ + /** + * Upload successful. + */ + ANASTASIS_SHARE_STATUS_SUCCESS = 0, + + /** + * Upload requires payment. + */ + ANASTASIS_SHARE_STATUS_PAYMENT_REQUIRED, + + /** + * Failure to upload secret share at the provider. + */ + ANASTASIS_SHARE_STATUS_PROVIDER_FAILED +}; + + +/** + * Per-provider status upon successful backup. + */ +struct ANASTASIS_ProviderSuccessStatus +{ + /** + * Base URL of the provider. + */ + const char *provider_url; + + /** + * When will the policy expire? + */ + struct GNUNET_TIME_Absolute policy_expiration; + + /** + * Version number of the policy at the provider. + */ + unsigned long long policy_version; + +}; + + +/** + * Complete result of a secret sharing operation. + */ +struct ANASTASIS_ShareResult +{ + /** + * Status of the share secret operation. + */ + enum ANASTASIS_ShareStatus ss; + + /** + * Details about the result, depending on @e ss. + */ + union + { + + struct + { + + /** + * Array of status details for each provider. + */ + const struct ANASTASIS_ProviderSuccessStatus *pss; + + /** + * Length of the @e policy_version and @e provider_urls arrays. + */ + unsigned int num_providers; + + } success; + + struct + { + /** + * Array of URLs with requested payments. + */ + struct ANASTASIS_SharePaymentRequest *payment_requests; + + /** + * Length of the payment_requests array. + */ + unsigned int payment_requests_length; + } payment_required; + + struct + { + /** + * Base URL of the failed provider. + */ + const char *provider_url; + + /** + * HTTP status returned by the provider. + */ + unsigned int http_status; + + /** + * Upload status of the provider. + */ + enum ANASTASIS_UploadStatus ec; + + + } provider_failure; + + } details; + +}; + + +/** + * Function called with the results of a #ANASTASIS_secret_share(). + * + * @param cls closure + * @param sr share result + */ +typedef void +(*ANASTASIS_ShareResultCallback)(void *cls, + const struct ANASTASIS_ShareResult *sr); + + +/** + * Defines a recovery document upload process (recovery document + * consists of multiple policies) + */ +struct ANASTASIS_SecretShare; + + +/** + * Details of a past payment + */ +struct ANASTASIS_ProviderDetails +{ + /** + * URL of the provider backend. + */ + const char *provider_url; + + /** + * Payment order ID / secret of a past payment. + */ + struct ANASTASIS_PaymentSecretP payment_secret; + + /** + * Server salt. Points into a truth object from which we got the + * salt. + */ + struct ANASTASIS_CRYPTO_ProviderSaltP provider_salt; +}; + + +/** + * Creates a recovery document with the created policies and uploads it to + * all servers. + * + * @param ctx the CURL context used to connect to the backend + * @param id_data used to create a account identifier on the escrow provider + * @param providers array of providers with URLs to upload the policies to + * @param pss_length length of the @a providers array + * @param policies list of policies which are included in this recovery document + * @param policies_length length of the @a policies array + * @param payment_years_requested for how many years would the client like the service to store the truth? + * @param pay_timeout how long to wait for payment + * @param spc payment callback is opened to pay the upload + * @param spc_cls closure for the @a spc payment callback + * @param src callback for the upload process + * @param src_cls closure for the @a src upload callback + * @param secret_name name of the core secret + * @param core_secret input of the user which is secured by anastasis e.g. (wallet private key) + * @param core_secret_size size of the @a core_secret + * @return NULL on error + */ +struct ANASTASIS_SecretShare * +ANASTASIS_secret_share (struct GNUNET_CURL_Context *ctx, + const json_t *id_data, + const struct ANASTASIS_ProviderDetails providers[], + unsigned int pss_length, + const struct ANASTASIS_Policy *policies[], + unsigned int policies_len, + uint32_t payment_years_requested, + struct GNUNET_TIME_Relative pay_timeout, + ANASTASIS_ShareResultCallback src, + void *src_cls, + const char *secret_name, + const void *core_secret, + size_t core_secret_size); + + +/** + * Cancels a secret share request. + * + * @param ss handle to the request + */ +void +ANASTASIS_secret_share_cancel (struct ANASTASIS_SecretShare *ss); + + +#endif diff --git a/src/include/anastasis_authorization_lib.h b/src/include/anastasis_authorization_lib.h new file mode 100644 index 0000000..80740be --- /dev/null +++ b/src/include/anastasis_authorization_lib.h @@ -0,0 +1,52 @@ +/* + This file is part of Anastasis + Copyright (C) 2019, 2021 Taler Systems SA + + Anastasis is free software; you can redistribute it and/or modify it under the + terms of the GNU Lesser General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/> +*/ +/** + * @file include/anastasis_authorization_lib.h + * @brief database plugin loader + * @author Dominik Meister + * @author Dennis Neufeld + * @author Christian Grothoff + */ +#ifndef ANASTASIS_AUTHORIZATION_LIB_H +#define ANASTASIS_AUTHORIZATION_LIB_H + +#include "anastasis_authorization_plugin.h" + +/** + * Load authorization plugin. + * + * @param method name of the method to load + * @param AH_cfg configuration to use + * @param[out] set to the cost for using the plugin during recovery + * @return #GNUNET_OK on success + */ +struct ANASTASIS_AuthorizationPlugin * +ANASTASIS_authorization_plugin_load ( + const char *method, + const struct GNUNET_CONFIGURATION_Handle *AH_cfg, + struct TALER_Amount *cost); + + +/** + * shutdown all loaded plugins. + * + * @param void + */ +void +ANASTASIS_authorization_plugin_shutdown (void); + +#endif +/* end of anastasis_authorization_lib.h */ diff --git a/src/include/anastasis_authorization_plugin.h b/src/include/anastasis_authorization_plugin.h new file mode 100644 index 0000000..5985f52 --- /dev/null +++ b/src/include/anastasis_authorization_plugin.h @@ -0,0 +1,183 @@ +/* + This file is part of Anastasis + Copyright (C) 2019 Taler Systems SA + + Anastasis is free software; you can redistribute it and/or modify it under the + terms of the GNU Lesser General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/> +*/ +/** + * @file include/anastasis_authorization_plugin.h + * @brief authorization access for Anastasis + * @author Christian Grothoff + */ +#ifndef ANASTASIS_AUTHORIZATION_PLUGIN_H +#define ANASTASIS_AUTHORIZATION_PLUGIN_H + +#include "anastasis_service.h" +#include <taler/taler_util.h> + + +/** + * Plugin-specific state for an authorization operation. + */ +struct ANASTASIS_AUTHORIZATION_State; + + +/** + * Enumeration values indicating the various possible + * outcomes of the plugin's `process` function. + */ +enum ANASTASIS_AUTHORIZATION_Result +{ + /** + * We successfully sent the authorization challenge + * and queued a reply to MHD. + */ + ANASTASIS_AUTHORIZATION_RES_SUCCESS = 0, + + /** + * We failed to transmit the authorization challenge, + * but successfully queued a failure response to MHD. + */ + ANASTASIS_AUTHORIZATION_RES_FAILED = 1, + + /** + * The plugin suspended the MHD connection as it needs some more + * time to do its (asynchronous) work before we can proceed. The + * plugin will resume the MHD connection when its work is done, and + * then the `process` function should be called again. + */ + ANASTASIS_AUTHORIZATION_RES_SUSPENDED = 2, + + /** + * The plugin tried to queue a reply on the MHD connection and + * failed to do so. We should return #MHD_NO to MHD to cause the + * HTTP connection to be closed without any reply. + * + * However, we were successful at transmitting the challenge, + * so the challenge should be marked as sent. + */ + ANASTASIS_AUTHORIZATION_RES_SUCCESS_REPLY_FAILED = 4, + + /** + * The plugin tried to queue a reply on the MHD connection and + * failed to do so. We should return #MHD_NO to MHD to cause the + * HTTP connection to be closed without any reply. + * + * Additionally, we failed to transmit the challenge. + */ + ANASTASIS_AUTHORIZATION_RES_FAILED_REPLY_FAILED = 5 +}; + + +/** + * Handle to interact with a authorization backend. + */ +struct ANASTASIS_AuthorizationPlugin +{ + + /** + * Closure for all callbacks. + */ + void *cls; + + /** + * How long should a generated challenge be valid for this type of method. + */ + struct GNUNET_TIME_Relative code_validity_period; + + /** + * How long before we should rotate a challenge for this type of method. + */ + struct GNUNET_TIME_Relative code_rotation_period; + + /** + * How long before we should retransmit a code. + */ + struct GNUNET_TIME_Relative code_retransmission_frequency; + + /** + * Validate @a data is a well-formed input into the challenge method, + * i.e. @a data is a well-formed phone number for sending an SMS, or + * a well-formed e-mail address for sending an e-mail. Not expected to + * check that the phone number or e-mail account actually exists. + * + * To be possibly used before issuing a 402 payment required to the client. + * + * @param cls closure + * @param connection HTTP client request (for queuing response) + * @param truth_mime mime type of @e data + * @param data input to validate (i.e. is it a valid phone number, etc.) + * @param data_length number of bytes in @a data + * @return #GNUNET_OK if @a data is valid, + * #GNUNET_NO if @a data is invalid and a reply was successfully queued on @a connection + * #GNUNET_SYSERR if @a data invalid but we failed to queue a reply on @a connection + */ + enum GNUNET_GenericReturnValue + (*validate)(void *cls, + struct MHD_Connection *connection, + const char *truth_mime, + const char *data, + size_t data_length); + + + /** + * Begin issuing authentication challenge to user based on @a data. + * I.e. start to send SMS or e-mail or launch video identification, + * or at least setup our authorization state (actual processing + * may also be startedin the @e process function). + * + * @param cls closure + * @param trigger function to call when we made progress + * @param trigger_cls closure for @a trigger + * @param truth_public_key Identifier of the challenge, to be (if possible) included in the + * interaction with the user + * @param code secret code that the user has to provide back to satisfy the challenge in + * the main anastasis protocol + * @param auth_command authentication command which is executed + * @param data input to validate (i.e. is it a valid phone number, etc.) + * @return state to track progress on the authorization operation, NULL on failure + */ + struct ANASTASIS_AUTHORIZATION_State * + (*start)(void *cls, + GNUNET_SCHEDULER_TaskCallback trigger, + void *trigger_cls, + const struct ANASTASIS_CRYPTO_TruthUUIDP *truth_public_key, + uint64_t code, + const void *data, + size_t data_length); + + + /** + * Continue issuing authentication challenge to user based on @a data. + * I.e. check if the transmission of the challenge via SMS or e-mail + * has completed and/or manipulate @a connection to redirect the client + * to a video identification site. + * + * @param as authorization state + * @param connection HTTP client request (for queuing response, such as redirection to video portal) + * @return state of the request + */ + enum ANASTASIS_AUTHORIZATION_Result + (*process)(struct ANASTASIS_AUTHORIZATION_State *as, + struct MHD_Connection *connection); + + + /** + * Free internal state associated with @a as. + * + * @param as state to clean up + */ + void + (*cleanup)(struct ANASTASIS_AUTHORIZATION_State *as); + +}; +#endif diff --git a/src/include/anastasis_crypto_lib.h b/src/include/anastasis_crypto_lib.h new file mode 100644 index 0000000..bf29b27 --- /dev/null +++ b/src/include/anastasis_crypto_lib.h @@ -0,0 +1,533 @@ +/* + This file is part of Anastasis + Copyright (C) 2020, 2021 Taler Systems SA + + Anastasis is free software; you can redistribute it and/or modify it under the + terms of the GNU Lesser General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/> +*/ +/** + * @file lib/anastasis_cryto_lib.h + * @brief anastasis crypto api + * @author Christian Grothoff + * @author Dominik Meister + * @author Dennis Neufeld + */ +#include <jansson.h> +#include <gnunet/gnunet_crypto_lib.h> + + +/** + * Server to client: this is the policy version. + */ +#define ANASTASIS_HTTP_HEADER_POLICY_VERSION "Anastasis-Version" + +/** + * Server to client: this is the policy expiration time. + */ +#define ANASTASIS_HTTP_HEADER_POLICY_EXPIRATION "Anastasis-Policy-Expiration" + +/** + * Client to server: use this to decrypt the truth. + */ +#define ANASTASIS_HTTP_HEADER_TRUTH_DECRYPTION_KEY \ + "Anastasis-Truth-Decryption-Key" + +/** + * Client to server: I paid using this payment secret. + */ +#define ANASTASIS_HTTP_HEADER_PAYMENT_IDENTIFIER "Anastasis-Payment-Identifier" + +/** + * Client to server: I am authorized to update this policy, or + * server to client: I prove this is a valid policy. + */ +#define ANASTASIS_HTTP_HEADER_POLICY_SIGNATURE "Anastasis-Policy-Signature" + +/** + * Server to client: Taler Payto-URI. + */ +#define ANASTASIS_HTTP_HEADER_TALER "Taler" + + +GNUNET_NETWORK_STRUCT_BEGIN + +/** + * An EdDSA public key that is used to identify a user's account. + */ +struct ANASTASIS_CRYPTO_AccountPublicKeyP +{ + struct GNUNET_CRYPTO_EddsaPublicKey pub; +}; + + +/** + * An EdDSA private key that is used to identify a user's account. + */ +struct ANASTASIS_CRYPTO_AccountPrivateKeyP +{ + struct GNUNET_CRYPTO_EddsaPrivateKey priv; +}; + + +/** + * A UUID that is used to identify a truth object + */ +struct ANASTASIS_CRYPTO_TruthUUIDP +{ + struct GNUNET_ShortHashCode uuid; +}; + + +/** + * Specifies a TruthKey which is used to decrypt the Truth stored by the user. + */ +struct ANASTASIS_CRYPTO_TruthKeyP +{ + struct GNUNET_HashCode key GNUNET_PACKED; +}; + + +/** + * Specifies a salt value used to encrypt the master public key. + */ +struct ANASTASIS_CRYPTO_MasterSaltP +{ + struct GNUNET_HashCode salt GNUNET_PACKED; +}; + + +/** + * Specifies a salt value used for salting the answer to a security question. + */ +struct ANASTASIS_CRYPTO_QuestionSaltP +{ + struct GNUNET_CRYPTO_PowSalt pow_salt; +}; + + +/** + * Specifies a salt value provided by an Anastasis provider, + * used for deriving the provider-specific user ID. + */ +struct ANASTASIS_CRYPTO_ProviderSaltP +{ + struct GNUNET_CRYPTO_PowSalt salt; +}; + + +/** + * Specifies a policy key which is used to decrypt the master key + */ +struct ANASTASIS_CRYPTO_PolicyKeyP +{ + struct GNUNET_HashCode key GNUNET_PACKED; +}; + + +/** + * Specifies an encrypted master key, the key is used to encrypt the core secret from the user + */ +struct ANASTASIS_CRYPTO_EncryptedMasterKeyP +{ + struct GNUNET_HashCode key GNUNET_PACKED; +}; + + +/** + * Specifies a Nonce used for the AES encryption, here defined as 32Byte large. + */ +struct ANASTASIS_CRYPTO_NonceP +{ + uint32_t nonce[8]; +}; + + +/** + * Specifies an IV used for the AES encryption, here defined as 16Byte large. + */ +struct ANASTASIS_CRYPTO_IvP +{ + uint32_t iv[4]; +}; + + +/** + * Specifies an symmetric key used for the AES encryption, here defined as 32Byte large. + */ +struct ANASTASIS_CRYPTO_SymKeyP +{ + uint32_t key[8]; +}; + + +/** + * Specifies an AES Tag used for the AES authentication, here defined as 16 Byte large. + */ +struct ANASTASIS_CRYPTO_AesTagP +{ + uint32_t aes_tag[4]; +}; + + +/** + * Specifies a Key Share from an escrow provider, the combined + * keyshares generate the EscrowMasterKey which is used to decrypt the + * Secret from the user. + */ +struct ANASTASIS_CRYPTO_KeyShareP +{ + uint32_t key[8]; +}; + + +/** + * Specifies an encrypted KeyShare + */ +struct ANASTASIS_CRYPTO_EncryptedKeyShareP +{ + /** + * Nonce used for the symmetric encryption. + */ + struct ANASTASIS_CRYPTO_NonceP nonce; + + /** + * GCM tag to check authenticity. + */ + struct ANASTASIS_CRYPTO_AesTagP tag; + + /** + * The actual key share. + */ + struct ANASTASIS_CRYPTO_KeyShareP keyshare; +}; + + +/** + * The escrow master key is the key used to encrypt the user secret (MasterKey). + */ +struct ANASTASIS_CRYPTO_EscrowMasterKeyP +{ + uint32_t key[8]; +}; + + +/** + * The user identifier consists of user information and the server salt. It is used as + * entropy source to generate the account public key and the encryption keys. + */ +struct ANASTASIS_CRYPTO_UserIdentifierP +{ + struct GNUNET_HashCode hash GNUNET_PACKED; +}; + + +/** + * Random identifier used to later charge a payment. + */ +struct ANASTASIS_PaymentSecretP +{ + uint32_t id[8]; +}; + + +/** + * Data signed by the account public key of a sync client to + * authorize the upload of the backup. + */ +struct ANASTASIS_UploadSignaturePS +{ + /** + * Set to #TALER_SIGNATURE_ANASTASIS_POLICY_UPLOAD. + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + + /** + * Hash of the new backup. + */ + struct GNUNET_HashCode new_recovery_data_hash; + +}; + + +/** + * Signature made with an account's public key. + */ +struct ANASTASIS_AccountSignatureP +{ + /** + * We use EdDSA. + */ + struct GNUNET_CRYPTO_EddsaSignature eddsa_sig; +}; + + +GNUNET_NETWORK_STRUCT_END + + +/** + * Hash a numerical answer to compute the hash value to be submitted + * to the server for verification. Useful for PINs and SMS-TANs and + * other numbers submitted for challenges. + * + * @param code the numeric value to hash + * @param[out] hashed_code the resulting hash value to submit to the Anastasis server + */ +void +ANASTASIS_hash_answer (uint64_t code, + struct GNUNET_HashCode *hashed_code); + + +/** + * Creates the UserIdentifier, it is used as entropy source for the + * encryption keys and for the public and private key for signing the + * data. + * + * @param id_data JSON encoded data, which contains the raw user secret + * @param server_salt salt from the server (escrow provider) + * @param[out] id reference to the id which was created + */ +void +ANASTASIS_CRYPTO_user_identifier_derive ( + const json_t *id_data, + const struct ANASTASIS_CRYPTO_ProviderSaltP *server_salt, + struct ANASTASIS_CRYPTO_UserIdentifierP *id); + + +/** + * Generates the eddsa public Key used as the account identifier on the providers + * + * @param id holds a hashed user secret which is used as entropy source for the public key generation + * @param[out] pub_key handle for the generated public key + */ +void +ANASTASIS_CRYPTO_account_public_key_derive ( + const struct ANASTASIS_CRYPTO_UserIdentifierP *id, + struct ANASTASIS_CRYPTO_AccountPublicKeyP *pub_key); + + +/** + * //FIXME combine these two + * Generates the eddsa public Key used as the account identifier on the providers + * + * @param id holds a hashed user secret which is used as entropy source for the public key generation + * @param[out] priv_key handle for the generated private key + */ +void +ANASTASIS_CRYPTO_account_private_key_derive ( + const struct ANASTASIS_CRYPTO_UserIdentifierP *id, + struct ANASTASIS_CRYPTO_AccountPrivateKeyP *priv_key); + + +/** + * Hash @a answer to security question with @a salt and @a uuid to compute + * @a result that would be sent to the service for authorization. + * + * @param answer human answer to a security question + * @param uuid the truth UUID (known to the service) + * @param salt random salt value, unknown to the service + * @param[out] result where to write the resulting hash + */ +void +ANASTASIS_CRYPTO_secure_answer_hash ( + const char *answer, + const struct ANASTASIS_CRYPTO_TruthUUIDP *uuid, + const struct ANASTASIS_CRYPTO_QuestionSaltP *salt, + struct GNUNET_HashCode *result); + + +/** + * Encrypt and signs the recovery document with AES256, the recovery + * document is encrypted with a derivation from the user identifier + * and the salt "erd". + * + * @param id Hashed User input, used for the generation of the encryption key + * @param rec_doc contains the recovery document as raw data + * @param rd_size defines the size of the recovery document inside data + * @param[out] enc_rec_doc return from the result, which contains the encrypted recovery document + * and the nonce and iv used for the encryption as Additional Data + * @param[out] erd_size size of the result + */ +void +ANASTASIS_CRYPTO_recovery_document_encrypt ( + const struct ANASTASIS_CRYPTO_UserIdentifierP *id, + const void *rec_doc, + size_t rd_size, + void **enc_rec_doc, + size_t *erd_size); + + +/** + * Decrypts the recovery document with AES256, the decryption key is generated with + * the user identifier provided by the user and the salt "erd". The nonce and IV used for the encryption + * are the first 48Byte of the data. + * + * @param id Hashed User input, used for the generation of the encryption key + * @param enc_rec_doc, contains the encrypted recovery document and the nonce and iv used for the encryption. + * @param erd_size size of the data + * @param[out] rec_doc return from the result, which contains the encrypted recovery document + * and the nonce and iv used for the encryption as Additional Data + * @param[out] rd_size size of the result + */ +void +ANASTASIS_CRYPTO_recovery_document_decrypt ( + const struct ANASTASIS_CRYPTO_UserIdentifierP *id, + const void *enc_rec_doc, + size_t erd_size, + void **rec_doc, + size_t *rd_size); + + +/** + * Encrypts a keyshare with a key generated with the user identification as entropy and the salt "eks". + * + * @param key_share the key share which is afterwards encrypted + * @param id the user identification which is the entropy source for the key generation + * @param xsalt answer to security question, otherwise NULL; used as extra salt in KDF + * @param[out] enc_key_share holds the encrypted share, the first 48 Bytes are the used nonce and tag + */ +void +ANASTASIS_CRYPTO_keyshare_encrypt ( + const struct ANASTASIS_CRYPTO_KeyShareP *key_share, + const struct ANASTASIS_CRYPTO_UserIdentifierP *id, + const char *xsalt, + struct ANASTASIS_CRYPTO_EncryptedKeyShareP *enc_key_share); + + +/** + * Decrypts a keyshare with a key generated with the user identification as entropy and the salt "eks". + * + * @param enc_key_share holds the encrypted share, the first 48 Bytes are the used nonce and tag + * @param id the user identification which is the entropy source for the key generation + * @param xsalt answer to security question, otherwise NULL; used as extra salt in KDF + * @param[out] key_share the result of decryption + */ +void +ANASTASIS_CRYPTO_keyshare_decrypt ( + const struct ANASTASIS_CRYPTO_EncryptedKeyShareP *enc_key_share, + const struct ANASTASIS_CRYPTO_UserIdentifierP *id, + const char *xsalt, + struct ANASTASIS_CRYPTO_KeyShareP *key_share); + + +/** + * Encrypts the truth data which contains the hashed answer or the + * phone number. It is encrypted with AES256, the key is generated + * with the user identification as entropy source and the salt "ect". + * + * @param nonce value to use for the nonce + * @param truth_enc_key master key used for encryption of the truth (see interface EscrowMethod) + * @param truth truth which will be encrypted + * @param truth_size size of the truth + * @param[out] enc_truth return from the result, which contains the encrypted truth + * and the nonce and iv used for the encryption as Additional Data + * @param[out] ect_size size of the result + */ +void +ANASTASIS_CRYPTO_truth_encrypt ( + const struct ANASTASIS_CRYPTO_NonceP *nonce, + const struct ANASTASIS_CRYPTO_TruthKeyP *truth_enc_key, + const void *truth, + size_t truth_size, + void **enc_truth, + size_t *ect_size); + + +/** + * Decrypts the truth data which contains the hashed answer or the phone number.. + * It is decrypted with AES256, the key is generated with the user identification as + * entropy source and the salt "ect". + * + * @param truth_enc_key master key used for encryption of the truth (see interface EscrowMethod) + * @param enc_truth truth holds the encrypted truth which will be decrypted + * @param ect_size size of the truth data + * @param truth return from the result, which contains the truth + * @param truth_size size of the result + */ +void +ANASTASIS_CRYPTO_truth_decrypt ( + const struct ANASTASIS_CRYPTO_TruthKeyP *truth_enc_key, + const void *enc_truth, + size_t ect_size, + void **truth, + size_t *truth_size); + + +/** + * A key share is randomly generated, one key share is generated for every + * truth a policy contains. + * + * @param key_share[out] reference to the created key share. + */ +void +ANASTASIS_CRYPTO_keyshare_create ( + struct ANASTASIS_CRYPTO_KeyShareP *key_share); + + +/** + * Once per policy a policy key is derived. The policy key consists of + * multiple key shares which are combined and hashed. + * + * @param key_shares list of key shares which are combined + * @param keyshare_length amount of key shares inside the array + * @param salt salt value + * @param[out] policy_key reference to the created key + */ +void +ANASTASIS_CRYPTO_policy_key_derive ( + const struct ANASTASIS_CRYPTO_KeyShareP *key_shares, + unsigned int keyshare_length, + const struct ANASTASIS_CRYPTO_MasterSaltP *salt, + struct ANASTASIS_CRYPTO_PolicyKeyP *policy_key); + + +/** + * The core secret is the user provided secret which will be saved with Anastasis. + * The secret will be encrypted with the master key, the master key is a random key which will + * be generated. The master key afterwards will be encrypted with the different policy keys. + * Encryption is performed with AES256 + * + * @param policy_keys an array of policy keys which are used to encrypt the master key + * @param policy_keys_length defines the amount of policy keys and also the amount of encrypted master keys + * @param core_secret the user provided core secret which is secured by anastasis + * @param core_secret_size the size of the core secret + * @param[out] enc_core_secret the core secret is encrypted with the generated master key + * @param[out] encrypted_master_keys array of encrypted master keys which will be safed inside the policies one encrypted + * master key is created for each policy key + */ +void +ANASTASIS_CRYPTO_core_secret_encrypt ( + const struct ANASTASIS_CRYPTO_PolicyKeyP *policy_keys, + unsigned int policy_keys_length, + const void *core_secret, + size_t core_secret_size, + void **enc_core_secret, + struct ANASTASIS_CRYPTO_EncryptedMasterKeyP *encrypted_master_keys); + + +/** + * Decrypts the core secret with the master key. First the master key is decrypted with the provided policy key. + * Afterwards the core secret is encrypted with the master key. The core secret is returned. + * + * @param encrypted_master_key master key for decrypting the core secret, is itself encrypted by the policy key + * @param policy_key built policy key which will decrypt the master key + * @param encrypted_core_secret the encrypted core secret from the user, will be encrypted with the policy key + * @param encrypted_core_secret_size size of the encrypted core secret + * @param[out] core_secret decrypted core secret will be returned + * @param[out] core_secret_size size of core secret + */ +void +ANASTASIS_CRYPTO_core_secret_recover ( + const struct ANASTASIS_CRYPTO_EncryptedMasterKeyP *encrypted_master_key, + const struct ANASTASIS_CRYPTO_PolicyKeyP *policy_key, + const void *encrypted_core_secret, + size_t encrypted_core_secret_size, + void **core_secret, + size_t *core_secret_size); diff --git a/src/include/anastasis_database_lib.h b/src/include/anastasis_database_lib.h new file mode 100644 index 0000000..4b33ea8 --- /dev/null +++ b/src/include/anastasis_database_lib.h @@ -0,0 +1,49 @@ +/* + This file is part of Anastasis + Copyright (C) 2019 Taler Systems SA + + Anastasis is free software; you can redistribute it and/or modify it under the + terms of the GNU Lesser General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/> +*/ +/** + * @file include/anastasis_database_lib.h + * @brief database plugin loader + * @author Dominik Meister + * @author Dennis Neufeld + * @author Christian Grothoff + */ +#ifndef ANASTASIS_DB_LIB_H +#define ANASTASIS_DB_LIB_H + +#include "anastasis_database_plugin.h" + +/** + * Initialize the plugin. + * + * @param cfg configuration to use + * @return NULL on failure + */ +struct ANASTASIS_DatabasePlugin * +ANASTASIS_DB_plugin_load (const struct GNUNET_CONFIGURATION_Handle *cfg); + + +/** + * Shutdown the plugin. + * + * @param plugin plugin to unload + */ +void +ANASTASIS_DB_plugin_unload (struct ANASTASIS_DatabasePlugin *plugin); + + +#endif /* ANASTASIS_DB_LIB_H */ + +/* end of anastasis_database_lib.h */ diff --git a/src/include/anastasis_database_plugin.h b/src/include/anastasis_database_plugin.h new file mode 100644 index 0000000..488a5af --- /dev/null +++ b/src/include/anastasis_database_plugin.h @@ -0,0 +1,655 @@ +/* + This file is part of Anastasis + Copyright (C) 2019 Taler Systems SA + + Anastasis is free software; you can redistribute it and/or modify it under the + terms of the GNU Lesser General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/> +*/ +/** + * @file include/anastasis_database_plugin.h + * @brief database access for Anastasis + * @author Christian Grothoff + */ +#ifndef ANASTASIS_DATABASE_PLUGIN_H +#define ANASTASIS_DATABASE_PLUGIN_H + +#include "anastasis_service.h" +#include <gnunet/gnunet_db_lib.h> + +/** + * How long is an offer for a challenge payment valid for payment? + */ +#define ANASTASIS_CHALLENGE_OFFER_LIFETIME GNUNET_TIME_UNIT_HOURS + +/** + * Return values for checking code validity. + */ +enum ANASTASIS_DB_CodeStatus +{ + /** + * Provided authentication code does not match database content. + */ + ANASTASIS_DB_CODE_STATUS_CHALLENGE_CODE_MISMATCH = -3, + + /** + * Encountered hard error talking to DB. + */ + ANASTASIS_DB_CODE_STATUS_HARD_ERROR = -2, + + /** + * Encountered serialization error talking to DB. + */ + ANASTASIS_DB_CODE_STATUS_SOFT_ERROR = -1, + + /** + * We have no challenge in the database. + */ + ANASTASIS_DB_CODE_STATUS_NO_RESULTS = 0, + + /** + * The provided challenge matches what we have in the database. + */ + ANASTASIS_DB_CODE_STATUS_VALID_CODE_STORED = 1, +}; + + +/** + * Return values for checking account validity. + */ +enum ANASTASIS_DB_AccountStatus +{ + /** + * Account is unknown, user should pay to establish it. + */ + ANASTASIS_DB_ACCOUNT_STATUS_PAYMENT_REQUIRED = -3, + + /** + * Encountered hard error talking to DB. + */ + ANASTASIS_DB_ACCOUNT_STATUS_HARD_ERROR = -2, + + /** + * Account is valid, but we have no policy stored yet. + */ + ANASTASIS_DB_ACCOUNT_STATUS_NO_RESULTS = 0, + + /** + * Account is valid, and we have a policy stored. + */ + ANASTASIS_DB_ACCOUNT_STATUS_VALID_HASH_RETURNED = 1, +}; + + +/** + * Return values for storing data in database with payment. + */ +enum ANASTASIS_DB_StoreStatus +{ + /** + * The client has stored too many policies, should pay to store more. + */ + ANASTASIS_DB_STORE_STATUS_STORE_LIMIT_EXCEEDED = -4, + + /** + * The client needs to pay to store policies. + */ + ANASTASIS_DB_STORE_STATUS_PAYMENT_REQUIRED = -3, + + /** + * Encountered hard error talking to DB. + */ + ANASTASIS_DB_STORE_STATUS_HARD_ERROR = -2, + + /** + * Despite retrying, we encountered serialization errors. + */ + ANASTASIS_DB_STORE_STATUS_SOFT_ERROR = -1, + + /** + * Database did not need an update (document exists). + */ + ANASTASIS_DB_STORE_STATUS_NO_RESULTS = 0, + + /** + * We successfully stored the document. + */ + ANASTASIS_DB_STORE_STATUS_SUCCESS = 1, +}; + + +/** + * Function called on all pending payments for an account or challenge. + * + * @param cls closure + * @param timestamp for how long have we been waiting + * @param payment_secret payment secret / order id in the backend + * @param amount how much is the order for + */ +typedef void +(*ANASTASIS_DB_PaymentPendingIterator)( + void *cls, + struct GNUNET_TIME_Absolute timestamp, + const struct ANASTASIS_PaymentSecretP *payment_secret, + const struct TALER_Amount *amount); + + +/** + * Handle to interact with the database. + * + * Functions ending with "_TR" run their OWN transaction scope + * and MUST NOT be called from within a transaction setup by the + * caller. Functions ending with "_NT" require the caller to + * setup a transaction scope. Functions without a suffix are + * simple, single SQL queries that MAY be used either way. + */ +struct ANASTASIS_DatabasePlugin +{ + + /** + * Closure for all callbacks. + */ + void *cls; + + /** + * Name of the library which generated this plugin. Set by the + * plugin loader. + */ + char *library_name; + + /** + * Drop anastasis tables. Used for testcases. + * + * @param cls closure + * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure + */ + int + (*drop_tables) (void *cls); + + /** + * Function called to perform "garbage collection" on the + * database, expiring records we no longer require. Deletes + * all user records that are not paid up (and by cascade deletes + * the associated recovery documents). Also deletes expired + * truth and financial records older than @a fin_expire. + * + * @param cls closure + * @param expire_backups backups older than the given time stamp should be garbage collected + * @param expire_pending_payments payments still pending from since before + * this value should be garbage collected + * @return transaction status + */ + enum GNUNET_DB_QueryStatus + (*gc)(void *cls, + struct GNUNET_TIME_Absolute expire, + struct GNUNET_TIME_Absolute expire_pending_payments); + + /** + * Do a pre-flight check that we are not in an uncommitted transaction. + * If we are, try to commit the previous transaction and output a warning. + * Does not return anything, as we will continue regardless of the outcome. + * + * @param cls the `struct PostgresClosure` with the plugin-specific state + */ + void + (*preflight) (void *cls); + + /** + * Check that the database connection is still up. + * + * @param pg connection to check + */ + void + (*check_connection) (void *cls); + + /** + * Roll back the current transaction of a database connection. + * + * @param cls the `struct PostgresClosure` with the plugin-specific state + * @return #GNUNET_OK on success + */ + void + (*rollback) (void *cls); + + /** + * Start a transaction. + * + * @param cls the `struct PostgresClosure` with the plugin-specific state + * @param name unique name identifying the transaction (for debugging), + * must point to a constant + * @return #GNUNET_OK on success + */ + int + (*start) (void *cls, + const char *name); + + /** + * Commit the current transaction of a database connection. + * + * @param cls the `struct PostgresClosure` with the plugin-specific state + * @return transaction status code + */ + enum GNUNET_DB_QueryStatus + (*commit)(void *cls); + + + /** + * Store encrypted recovery document. + * + * @param cls closure + * @param anastasis_pub public key of the user's account + * @param account_sig signature affirming storage request + * @param data_hash hash of @a data + * @param data contains encrypted_recovery_document + * @param data_size size of data blob + * @param payment_secret identifier for the payment, used to later charge on uploads + * @param[out] version set to the version assigned to the document by the database + * @return transaction status, 0 if upload could not be finished because @a payment_secret + * did not have enough upload left; HARD error if @a payment_secret is unknown, ... + */ + enum ANASTASIS_DB_StoreStatus + (*store_recovery_document)( + void *cls, + const struct ANASTASIS_CRYPTO_AccountPublicKeyP *anastasis_pub, + const struct ANASTASIS_AccountSignatureP *account_sig, + const struct GNUNET_HashCode *data_hash, + const void *data, + size_t data_size, + const struct ANASTASIS_PaymentSecretP *payment_secret, + uint32_t *version); + + + /** + * Fetch recovery document for user according given version. + * + * @param cls closure + * @param anastasis_pub public key of the user's account + * @param version the version number of the policy the user requests + * @param[out] account_sig signature + * @param[out] recovery_data_hash hash of the current recovery data + * @param[out] data_size size of data blob + * @param[out] data blob which contains the recovery document + * @return transaction status + */ + enum GNUNET_DB_QueryStatus + (*get_recovery_document)( + void *cls, + const struct ANASTASIS_CRYPTO_AccountPublicKeyP *anastasis_pub, + uint32_t version, + struct ANASTASIS_AccountSignatureP *account_sig, + struct GNUNET_HashCode *recovery_data_hash, + size_t *data_size, + void **data); + + + /** + * Fetch latest recovery document for user. + * + * @param cls closure + * @param anastasis_pub public key of the user's account + * @param account_sig signature + * @param recovery_data_hash hash of the current recovery data + * @param[out] data_size set to size of @a data blob + * @param[out] data set to blob which contains the recovery document + * @param[out] version set to the version number of the policy being returned + * @return transaction status + */ + enum GNUNET_DB_QueryStatus + (*get_latest_recovery_document)( + void *cls, + const struct ANASTASIS_CRYPTO_AccountPublicKeyP *anastasis_pub, + struct ANASTASIS_AccountSignatureP *account_sig, + struct GNUNET_HashCode *recovery_data_hash, + size_t *data_size, + void **data, + uint32_t *version); + + + /** + * Upload Truth, which contains the Truth and the KeyShare. + * + * @param cls closure + * @param truth_uuid the identifier for the Truth + * @param key_share_data contains information of an EncryptedKeyShare + * @param method name of method + * @param nonce nonce used to compute encryption key for encrypted_truth + * @param aes_gcm_tag authentication tag of encrypted_truth + * @param encrypted_truth contains the encrypted Truth which includes the ground truth i.e. H(challenge answer), phonenumber, SMS + * @param encrypted_truth_size the size of the Truth + * @param truth_expiration time till the according data will be stored + * @return transaction status + */ + enum GNUNET_DB_QueryStatus + (*store_truth)( + void *cls, + const struct ANASTASIS_CRYPTO_TruthUUIDP *truth_uuid, + const struct ANASTASIS_CRYPTO_EncryptedKeyShareP *key_share_data, + const char *mime_type, + const void *encrypted_truth, + size_t encrypted_truth_size, + const char *method, + struct GNUNET_TIME_Relative truth_expiration); + + + /** + * Get the encrypted truth to validate the challenge response + * + * @param cls closure + * @param truth_uuid the identifier for the Truth + * @param[out] truth contains the encrypted truth + * @param[out] truth_size size of the encrypted truth + * @param[out] truth_mime mime type of truth + * @param[out] method type of the challenge + * @return transaction status + */ + enum GNUNET_DB_QueryStatus + (*get_escrow_challenge)( + void *cls, + const struct ANASTASIS_CRYPTO_TruthUUIDP *truth_uuid, + void **truth, + size_t *truth_size, + char **truth_mime, + char **method); + + + /** + * Lookup (encrypted) key share by @a truth_uuid. + * + * @param cls closure + * @param truth_uuid the identifier for the Truth + * @param[out] key_share set to the encrypted Keyshare + * @return transaction status + */ + enum GNUNET_DB_QueryStatus + (*get_key_share)( + void *cls, + const struct ANASTASIS_CRYPTO_TruthUUIDP *truth_uuid, + struct ANASTASIS_CRYPTO_EncryptedKeyShareP *key_share); + + + /** + * Check if an account exists, and if so, return the + * current @a recovery_document_hash. + * + * @param cls closure + * @param anastasis_pub account identifier + * @param[out] paid_until until when is the account paid up? + * @param[out] recovery_data_hash set to hash of @a recovery document + * @param[out] version set to the recovery policy version + * @return transaction status + */ + enum ANASTASIS_DB_AccountStatus + (*lookup_account)( + void *cls, + const struct ANASTASIS_CRYPTO_AccountPublicKeyP *anastasis_pub, + struct GNUNET_TIME_Absolute *paid_until, + struct GNUNET_HashCode *recovery_data_hash, + uint32_t *version); + + + /** + * Check payment identifier. Used to check if a payment identifier given by + * the user is valid (existing and paid). + * + * @param cls closure + * @param payment_secret payment secret which the user must provide with every upload + * @param[out] paid bool value to show if payment is paid + * @param[out] valid_counter bool value to show if post_counter is > 0 + * @return transaction status + */ + enum GNUNET_DB_QueryStatus + (*check_payment_identifier)( + void *cls, + const struct ANASTASIS_PaymentSecretP *payment_secret, + bool *paid, + bool *valid_counter); + + + /** + * Check payment identifier. Used to check if a payment identifier given by + * the user is valid (existing and paid). + * + * @param cls closure + * @param payment_secret payment secret which the user must provide with every upload + * @param truth_uuid unique identifier of the truth the user must satisfy the challenge + * @param[out] paid bool value to show if payment is paid + * @param[out] valid_counter bool value to show if post_counter is > 0 + * @return transaction status + */ + enum GNUNET_DB_QueryStatus + (*check_challenge_payment)( + void *cls, + const struct ANASTASIS_PaymentSecretP *payment_secret, + const struct ANASTASIS_CRYPTO_TruthUUIDP *truth_uuid, + bool *paid); + + + /** + * Increment account lifetime by @a lifetime. + * + * @param cls closure + * @param account_pub which account received a payment + * @param payment_identifier proof of payment, must be unique and match pending payment + * @param lifetime for how long is the account now paid (increment) + * @param[out] paid_until set to the end of the lifetime after the operation + * @return transaction status + */ + enum GNUNET_DB_QueryStatus + (*increment_lifetime)( + void *cls, + const struct ANASTASIS_CRYPTO_AccountPublicKeyP *anastasis_pub, + const struct ANASTASIS_PaymentSecretP *payment_identifier, + struct GNUNET_TIME_Relative lifetime, + struct GNUNET_TIME_Absolute *paid_until); + + + /** + * Update account lifetime to the maximum of the current + * value and @a eol. + * + * @param cls closure + * @param account_pub which account received a payment + * @param payment_identifier proof of payment, must be unique and match pending payment + * @param eol for how long is the account now paid (absolute) + * @return transaction status + */ + enum GNUNET_DB_QueryStatus + (*update_lifetime)( + void *cls, + const struct ANASTASIS_CRYPTO_AccountPublicKeyP *anastasis_pub, + const struct ANASTASIS_PaymentSecretP *payment_identifier, + struct GNUNET_TIME_Absolute eol); + + + /** + * Store payment. Used to begin a payment, not indicative + * that the payment actually was made. (That is done + * when we increment the account's lifetime.) + * + * @param cls closure + * @param anastasis_pub anastasis's public key + * @param post_counter how many uploads does @a amount pay for + * @param payment_secret payment secret which the user must provide with every upload + * @param amount how much we asked for + * @return transaction status + */ + enum GNUNET_DB_QueryStatus + (*record_recdoc_payment)( + void *cls, + const struct ANASTASIS_CRYPTO_AccountPublicKeyP *anastasis_pub, + uint32_t post_counter, + const struct ANASTASIS_PaymentSecretP *payment_secret, + const struct TALER_Amount *amount); + + + /** + * Record truth upload payment was made. + * + * @param cls closure + * @param uuid the truth's UUID + * @param amount the amount that was paid + * @param duration how long is the truth paid for + * @return transaction status + */ + enum GNUNET_DB_QueryStatus + (*record_truth_upload_payment)( + void *cls, + const struct ANASTASIS_CRYPTO_TruthUUIDP *uuid, + const struct TALER_Amount *amount, + struct GNUNET_TIME_Relative duration); + + + /** + * Inquire whether truth upload payment was made. + * + * @param cls closure + * @param uuid the truth's UUID + * @param[out] paid_until set for how long this truth is paid for + * @return transaction status + */ + enum GNUNET_DB_QueryStatus + (*check_truth_upload_paid)( + void *cls, + const struct ANASTASIS_CRYPTO_TruthUUIDP *uuid, + struct GNUNET_TIME_Absolute *paid_until); + + + /** + * Verify the provided code with the code on the server. + * If the code matches the function will return with success, if the code + * does not match, the retry counter will be decreased by one. + * + * @param cls closure + * @param truth_pub identification of the challenge which the code corresponds to + * @param hashed_code code which the user provided and wants to verify + * @return transaction status + */ + enum ANASTASIS_DB_CodeStatus + (*verify_challenge_code)( + void *cls, + const struct ANASTASIS_CRYPTO_TruthUUIDP *truth_pub, + const struct GNUNET_HashCode *hashed_code); + + /** + * Insert a new challenge code for a given challenge identified by the challenge + * public key. The function will first check if there is already a valid code + * for this challenge present and won't insert a new one in this case. + * + * @param cls closure + * @param truth_uuid the identifier for the challenge + * @param rotation_period for how long is the code available + * @param validity_period for how long is the code available + * @param retry_counter amount of retries allowed + * @param[out] retransmission_date when to next retransmit + * @param[out] code set to the code which will be checked for later + * @return transaction status, + * #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if we are out of valid tries, + * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT if @a code is now in the DB + */ + enum GNUNET_DB_QueryStatus + (*create_challenge_code)( + void *cls, + const struct ANASTASIS_CRYPTO_TruthUUIDP *truth_uuid, + struct GNUNET_TIME_Relative rotation_period, + struct GNUNET_TIME_Relative validity_period, + unsigned int retry_counter, + struct GNUNET_TIME_Absolute *retransmission_date, + uint64_t *code); + + + /** + * Remember in the database that we successfully sent a challenge. + * + * @param cls closure + * @param truth_uuid the identifier for the challenge + * @param code the challenge that was sent + */ + enum GNUNET_DB_QueryStatus + (*mark_challenge_sent)( + void *cls, + const struct ANASTASIS_PaymentSecretP *payment_secret, + const struct ANASTASIS_CRYPTO_TruthUUIDP *truth_uuid, + uint64_t code); + + + /** + * Store payment for challenge. + * + * @param cls closure + * @param truth_key identifier of the challenge to pay + * @param payment_secret payment secret which the user must provide with every upload + * @param amount how much we asked for + * @return transaction status + */ + enum GNUNET_DB_QueryStatus + (*record_challenge_payment)( + void *cls, + const struct ANASTASIS_CRYPTO_TruthUUIDP *truth_uuid, + const struct ANASTASIS_PaymentSecretP *payment_secret, + const struct TALER_Amount *amount); + + + /** + * Record refund for challenge. + * + * @param cls closure + * @param truth_key identifier of the challenge to pay + * @param payment_secret payment secret which the user must provide with every upload + * @return transaction status + */ + enum GNUNET_DB_QueryStatus + (*record_challenge_refund)( + void *cls, + const struct ANASTASIS_CRYPTO_TruthUUIDP *truth_uuid, + const struct ANASTASIS_PaymentSecretP *payment_secret); + + + /** + * Lookup for a pending payment for a certain challenge + * + * @param cls closure + * @param truth_uuid identification of the challenge + * @param[out] payment_secret set to the challenge payment secret + * @return transaction status + */ + enum GNUNET_DB_QueryStatus + (*lookup_challenge_payment)( + void *cls, + const struct ANASTASIS_CRYPTO_TruthUUIDP *truth_uuid, + struct ANASTASIS_PaymentSecretP *payment_secret); + + + /** + * Update payment status of challenge + * + * @param cls closure + * @param truth_uuid which challenge received a payment + * @param payment_identifier proof of payment, must be unique and match pending payment + * @return transaction status + */ + enum GNUNET_DB_QueryStatus + (*update_challenge_payment)( + void *cls, + const struct ANASTASIS_CRYPTO_TruthUUIDP *truth_uuid, + const struct ANASTASIS_PaymentSecretP *payment_identifier); + + + /** + * Function called to remove all expired codes from the database. + * FIXME: maybe implement as part of @e gc() in the future. + * + * @return transaction status + */ + enum GNUNET_DB_QueryStatus + (*challenge_gc)(void *cls); + + +}; +#endif diff --git a/src/include/anastasis_json.h b/src/include/anastasis_json.h new file mode 100644 index 0000000..9e8d924 --- /dev/null +++ b/src/include/anastasis_json.h @@ -0,0 +1,410 @@ +/* + This file is part of Anastasis + Copyright (C) 2020 Taler Systems SA + + Anastasis is free software; you can redistribute it and/or modify it under the + terms of the GNU Lesser General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/> +*/ +/** + * @file lib/anastasis_json.h + * @brief anastasis de-/serialization api + * @author Christian Grothoff + * @author Dominik Meister + * @author Dennis Neufeld + */ +#ifndef ANASTASIS_JSON_H +#define ANASTASIS_JSON_H + +#include <jansson.h> +#include <gnunet/gnunet_util_lib.h> +#include "anastasis_error_codes.h" + +/** + * Enumeration of possible backup process status. + */ +enum ANASTASIS_BackupStatus +{ + ANASTASIS_BS_INITIAL, + ANASTASIS_BS_SELECT_CONTINENT, + ANASTASIS_BS_SELECT_COUNTRY, + ANASTASIS_BS_ENTER_USER_ATTRIBUTES, + ANASTASIS_BS_ADD_AUTHENTICATION_METHOD, + ANASTASIS_BS_ADD_POLICY, + ANASTASIS_BS_PAY +}; + +/** + * Enumeration of possible recovery process status. + */ +enum ANASTASIS_RecoveryStatus +{ + ANASTASIS_RS_INITIAL, + ANASTASIS_RS_SELECT_CONTINENT, + ANASTASIS_RS_SELECT_COUNTRY, + ANASTASIS_RS_ENTER_USER_ATTRIBUTES, + ANASTASIS_RS_SOLVE_CHALLENGE +}; + +// A state for the backup process. +struct ANASTASIS_BackupState +{ + enum ANASTASIS_BackupStatus status; + + union + { + + struct + { + // empty! + } select_continent; + + struct + { + const char *continent; + } select_country; + + struct + { + const char *continent; + const char *country; + const char *currency; // derived or per manual override! + json_t *user_attributes; + } enter_attributes; + + struct + { + const char *continent; + const char *country; + const char *currency; + json_t *user_attributes; + + struct AuthenticationDetails + { + enum AuthenticationMethod + { + SMS, + VIDEO, + SECQUEST, + EMAIL, + SNAILMAIL + }; + char *provider_url; + union Truth + { + + struct + { + char *phone_number; + } sms; + + struct + { + char *question; + char *answer; // FIXME: Reasonable to store answer in clear text here? + } secquest; + + struct + { + char *mailaddress; + } email; + + struct + { + char *full_name; + char *street; // street name + number + char *postal_code; + char *city; + char *country; + } snailmail; + + struct + { + char *path_to_picture; + } video; + } truth; + }*ad; // array + size_t ad_length; + } add_authentication; + struct + { + const char *continent; + const char *country; + const char *currency; + json_t *user_attributes; + + struct AuthenticationDetails + { + enum AuthenticationMethod + { + SMS, + VIDEO, + SECQUEST, + EMAIL, + SNAILMAIL + }; + char *provider_url; + union Truth + { + + struct + { + char *phone_number; + } sms; + + struct + { + char *question; + char *answer; // FIXME: Reasonable to store answer in clear text here? + } secquest; + + struct + { + char *mailaddress; + } email; + + struct + { + char *full_name; + char *street; // street name + number + char *postal_code; + char *city; + char *country; + } snailmail; + + struct + { + char *path_to_picture; + } video; + } truth; + }*ad; // array + size_t ad_length; + + struct PolicyDetails + { + struct AuthenticationDetails *ad; // array + }*pd; // array + size_t pd_length; + } add_policy; + // FIXME: add_payment + } details; +}; + + +// A state for the recovery process. +struct ANASTASIS_RecoveryState +{ + enum ANASTASIS_RecoveryStatus status; + + struct + { + // empty! + } select_continent; + + struct + { + const char *continent; + } select_country; + + struct + { + const char *continent; + const char *country; + const char *currency; // derived or per manual override! + json_t *user_attributes; + } enter_attributes; + + struct + { + const char *continent; + const char *country; + const char *currency; + json_t *user_attributes; + + struct ChallengeDetails + { + enum AuthenticationMethod + { + SMS, + VIDEO, + SECQUEST, + EMAIL, + SNAILMAIL + }; + char *provider_url; + union Challenge + { + + struct + { + char *phone_number; + char *code; + } sms; + + struct + { + char *question; + char *answer; // FIXME: Reasonable to store answer in clear text here? + } secquest; + + struct + { + char *mailaddress; + char *code; + } email; + + struct + { + char *full_name; + char *street; // street name + number + char *postal_code; + char *city; + char *country; + char *code; + } snailmail; + + struct + { + char *path_to_picture; + char *code; + } video; + } truth; + }*cd; // array + size_t cd_length; + } solve_challenge; +}; + +/** + * Definition of actions on ANASTASIS_BackupState. + */ +struct ANASTASIS_BackupAction +{ + enum action + { + ANASTASIS_BA_GET_SELECT_CONTINENT, + ANASTASIS_BA_GET_SELECT_COUNTRY, + ANASTASIS_BA_GET_ENTER_USER_ATTRIBUTES, + ANASTASIS_BA_GET_ADD_AUTHENTICATION_METHOD, + ANASTASIS_BA_GET_ADD_POLICY, + ANASTASIS_BA_GET_PAY, + ANASTASIS_BA_SET_SELECT_CONTINENT, + ANASTASIS_BA_SET_SELECT_COUNTRY, + ANASTASIS_BA_SET_ENTER_USER_ATTRIBUTES, + ANASTASIS_BA_SET_ADD_AUTHENTICATION_METHOD, + ANASTASIS_BA_SET_ADD_POLICY, + ANASTASIS_BA_SET_PAY + }; +}; + +/** + * Definition of actions on ANASTASIS_RecoveryState. + */ +struct ANASTASIS_RecoveryAction +{ + enum action + { + ANASTASIS_RS_GET_SELECT_CONTINENT, + ANASTASIS_RS_GET_SELECT_COUNTRY, + ANASTASIS_RS_GET_ENTER_USER_ATTRIBUTES, + ANASTASIS_RS_GET_SOLVE_CHALLENGE, + ANASTASIS_RS_SET_SELECT_CONTINENT, + ANASTASIS_RS_SET_SELECT_COUNTRY, + ANASTASIS_RS_SET_ENTER_USER_ATTRIBUTES, + ANASTASIS_RS_SET_SOLVE_CHALLENGE + }; +}; + + +/** + * Signature of the callback bassed to #ANASTASIS_apply_anastasis_backup_action + * for asynchronous actions on a #ANASTASIS_BackupState. + * + * @param cls closure + * @param new_bs the new #ANASTASIS_BackupState + * @param error error code + */ +typedef void +(*ANASTASIS_BackupApplyActionCallback)( + void *cls, + const struct ANASTASIS_BackupState *new_bs, + enum TALER_ErrorCode error); + + +/** + * Signature of the callback bassed to #ANASTASIS_apply_anastasis_recovery_action + * for asynchronous actions on a #ANASTASIS_RecoveryState. + * + * @param cls closure + * @param new_bs the new #ANASTASIS_RecoveryState + * @param error error code + */ +typedef void +(*ANASTASIS_RecoveryApplyActionCallback)( + void *cls, + const struct ANASTASIS_RecoveryState *new_rs, + enum TALER_ErrorCode error); + + +/** + * Returns an initial ANASTASIS_BackupState. + * + * @return initial ANASTASIS_BackupState + */ +struct ANASTASIS_BackupState * +ANASTASIS_get_initial_backup_state (); + + +/** + * Returns an initial ANASTASIS_RecoveryState. + * + * @return initial ANASTASIS_RecoveryState + */ +struct ANASTASIS_RecoveryState * +ANASTASIS_get_initial_recovery_state (); + + +/** + * Operates on a backup state depending on given #ANASTASIS_BackupState + * and #ANASTASIS_BackupAction. The new #ANASTASIS_BackupState is returned + * by a callback function. + * This function can do network access to talk to anastasis service providers. + * + * @param ctx url context for the event loop + * @param bs the previous *ANASTASIS_BackupState + * @param ba the action to do on #ANASTASIS_BackupState + * @param cb callback function to call with the action + */ +void +ANASTASIS_apply_anastasis_backup_action ( + struct GNUNET_CURL_Context *ctx, + struct ANASTASIS_BackupState *bs, + struct ANASTASIS_BackupAction *ba, + ANASTASIS_BackupApplyActionCallback cb); + + +/** + * Operates on a recovery state depending on given #ANASTASIS_RecoveryState + * and #ANASTASIS_RecoveryAction. The new #ANASTASIS_RecoveryState is returned + * by a callback function. + * This function can do network access to talk to anastasis service providers. + * + * @param ctx url context for the event loop + * @param bs the previous *ANASTASIS_RecoveryState + * @param ba the action to do on #ANASTASIS_RecoveryState + * @param cb callback function to call with the action + */ +void +ANASTASIS_apply_anastasis_recovery_action ( + struct GNUNET_CURL_Context *ctx, + struct ANASTASIS_RecoveryState *rs, + struct ANASTASIS_RecoveryAction *ra, + ANASTASIS_RecoveryApplyActionCallback cb); + +#endif /* _ANASTASIS_JSON_H */
\ No newline at end of file diff --git a/src/include/anastasis_redux.h b/src/include/anastasis_redux.h new file mode 100644 index 0000000..7a0ff53 --- /dev/null +++ b/src/include/anastasis_redux.h @@ -0,0 +1,127 @@ +/* + This file is part of Anastasis + Copyright (C) 2020, 2021 Taler Systems SA + + Anastasis is free software; you can redistribute it and/or modify it under the + terms of the GNU Lesser General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/> +*/ +/** + * @file include/anastasis_redux.h + * @brief anastasis reducer api + * @author Christian Grothoff + * @author Dominik Meister + * @author Dennis Neufeld + */ +#ifndef ANASTASIS_REDUX_H +#define ANASTASIS_REDUX_H + +#include <jansson.h> +#include "anastasis.h" +#include <taler/taler_mhd_lib.h> +#include <regex.h> + + +/** + * Initialize reducer subsystem. + * + * @param ctx context to use for CURL requests. + */ +void +ANASTASIS_redux_init (struct GNUNET_CURL_Context *ctx); + + +/** + * Terminate reducer subsystem. + */ +void +ANASTASIS_redux_done (void); + + +/** + * Returns an initial ANASTASIS backup state. + * + * @return NULL on failure + */ +json_t * +ANASTASIS_backup_start (const struct GNUNET_CONFIGURATION_Handle *cfg); + + +/** + * Returns an initial ANASTASIS recovery state. + * + * @return NULL on failure + */ +json_t * +ANASTASIS_recovery_start (const struct GNUNET_CONFIGURATION_Handle *cfg); + + +/** + * Returns an initial ANASTASIS recovery state. + * + * @return NULL on failure + */ +json_t * +ANASTASIS_recovery_start (const struct GNUNET_CONFIGURATION_Handle *cfg); + + +/** + * Signature of the callback passed to #ANASTASIS_backup_action and + * #ANASTASIS_recover_action. + * + * @param cls closure + * @param error error code, #TALER_EC_NONE if @a new_bs is the new successful state + * @param new_state the new state of the operation (client should json_incref() to keep an alias) + */ +typedef void +(*ANASTASIS_ActionCallback)(void *cls, + enum TALER_ErrorCode error, + json_t *new_state); + + +/** + * Handle to an ongoing action. Only valid until the #ANASTASIS_ActionCallback is invoked. + */ +struct ANASTASIS_ReduxAction; + + +/** + * Operates on a state depending on given #ANASTASIS_BackupState + * or #ANASTASIS_RecoveryState and #ANASTASIS_BackupAction or + * #ANASTASIS_RecoveryAction. + * The new #ANASTASIS_BackupState or #ANASTASIS_RecoveryState is returned + * by a callback function. + * This function can do network access to talk to anastasis service providers. + * + * @param state input state + * @param action what action to perform + * @param arguments data for the @a action + * @param cb function to call with the result + * @param cb_cls closure for @a cb + * @return failure state or new state + */ +struct ANASTASIS_ReduxAction * +ANASTASIS_redux_action (const json_t *state, + const char *action, + const json_t *arguments, + ANASTASIS_ActionCallback cb, + void *cb_cls); + + +/** + * Cancel ongoing redux action. + * + * @param ra action to cancel + */ +void +ANASTASIS_redux_action_cancel (struct ANASTASIS_ReduxAction *ra); + + +#endif /* _ANASTASIS_REDUX_H */ diff --git a/src/include/anastasis_service.h b/src/include/anastasis_service.h new file mode 100644 index 0000000..98ac490 --- /dev/null +++ b/src/include/anastasis_service.h @@ -0,0 +1,703 @@ +/* + This file is part of TALER + Copyright (C) 2019-2021 Taler Systems SA + + Anastasis is free software; you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License along with + Anastasis; see the file COPYING.LIB. If not, see <http://www.gnu.org/licenses/> +*/ +/** + * @file include/anastasis_service.h + * @brief C interface of libanastasisrest, a C library to use merchant's HTTP API + * @author Christian Grothoff + * @author Dennis Neufeld + * @author Dominik Meister + */ +#ifndef ANASTASIS_SERVICE_H +#define ANASTASIS_SERVICE_H + +#include "anastasis_crypto_lib.h" +#include "anastasis_util_lib.h" +#include <gnunet/gnunet_curl_lib.h> +#include <jansson.h> + + +/** + * Anastasis authorization method configuration + */ +struct ANASTASIS_AuthorizationMethodConfig +{ + /** + * Type of the method, i.e. "question". + */ + const char *type; + + /** + * Fee charged for accessing key share using this method. + */ + struct TALER_Amount usage_fee; +}; + + +/** + * @brief Anastasis configuration data. + */ +struct ANASTASIS_Config +{ + /** + * Protocol version supported by the server. + */ + const char *version; + + /** + * Business name of the anastasis provider. + */ + const char *business_name; + + /** + * Currency used for payments by the server. + */ + const char *currency; + + /** + * Array of authorization methods supported by the server. + */ + const struct ANASTASIS_AuthorizationMethodConfig *methods; + + /** + * Length of the @e methods array. + */ + unsigned int methods_length; + + /** + * Maximum size of an upload in megabytes. + */ + uint32_t storage_limit_in_megabytes; + + /** + * Annual fee for an account / policy upload. + */ + struct TALER_Amount annual_fee; + + /** + * Fee for a truth upload. + */ + struct TALER_Amount truth_upload_fee; + + /** + * Maximum legal liability for data loss covered by the + * provider. + */ + struct TALER_Amount liability_limit; + + /** + * Server salt. + */ + struct ANASTASIS_CRYPTO_ProviderSaltP salt; + +}; + + +/** + * Function called with the result of a /config request. + * Note that an HTTP status of #MHD_HTTP_OK is no guarantee + * that @a acfg is non-NULL. @a acfg is non-NULL only if + * the server provided an acceptable response. + * + * @param cls closure + * @param http_status the HTTP status + * @param acfg configuration obtained, NULL if we could not parse it + */ +typedef void +(*ANASTASIS_ConfigCallback)(void *cls, + unsigned int http_status, + const struct ANASTASIS_Config *acfg); + + +/** + * @brief A Config Operation Handle + */ +struct ANASTASIS_ConfigOperation; + + +/** + * Run a GET /config request against the Anastasis backend. + * + * @param ctx CURL context to use + * @param base_url base URL fo the Anastasis backend + * @param cb function to call with the results + * @param cb_cls closure for @a cb + * @return handle to cancel the operation + */ +struct ANASTASIS_ConfigOperation * +ANASTASIS_get_config (struct GNUNET_CURL_Context *ctx, + const char *base_url, + ANASTASIS_ConfigCallback cb, + void *cb_cls); + + +/** + * Cancel ongoing #ANASTASIS_get_config() request. + * + * @param co configuration request to cancel. + */ +void +ANASTASIS_config_cancel (struct ANASTASIS_ConfigOperation *co); + + +/****** POLICY API ******/ + + +/** + * Detailed results from the successful download. + */ +struct ANASTASIS_DownloadDetails +{ + /** + * Signature (already verified). + */ + struct ANASTASIS_AccountSignatureP sig; + + /** + * Hash over @e policy and @e policy_size. + */ + struct GNUNET_HashCode curr_policy_hash; + + /** + * The backup we downloaded. + */ + const void *policy; + + /** + * Number of bytes in @e backup. + */ + size_t policy_size; + + /** + * Policy version returned by the service. + */ + uint32_t version; +}; + + +/** + * Handle for a GET /policy operation. + */ +struct ANASTASIS_PolicyLookupOperation; + + +/** + * Callback to process a GET /policy request + * + * @param cls closure + * @param http_status HTTP status code for this request + * @param ec anastasis-specific error code + * @param obj the response body + */ +typedef void +(*ANASTASIS_PolicyLookupCallback) (void *cls, + unsigned int http_status, + const struct ANASTASIS_DownloadDetails *dd); + + +/** + * Does a GET /policy. + * + * @param ctx execution context + * @param backend_url base URL of the merchant backend + * @param anastasis_pub public key of the user's account + * @param cb callback which will work the response gotten from the backend + * @param cb_cls closure to pass to the callback + * @return handle for this operation, NULL upon errors + */ +struct ANASTASIS_PolicyLookupOperation * +ANASTASIS_policy_lookup ( + struct GNUNET_CURL_Context *ctx, + const char *backend_url, + const struct ANASTASIS_CRYPTO_AccountPublicKeyP *anastasis_pub, + ANASTASIS_PolicyLookupCallback cb, + void *cb_cls); + + +/** + * Does a GET /policy for a specific version. + * + * @param ctx execution context + * @param backend_url base URL of the merchant backend + * @param anastasis_pub public key of the user's account + * @param cb callback which will work the response gotten from the backend + * @param cb_cls closure to pass to the callback + * @param version version of the policy to be requested + * @return handle for this operation, NULL upon errors + */ +struct ANASTASIS_PolicyLookupOperation * +ANASTASIS_policy_lookup_version ( + struct GNUNET_CURL_Context *ctx, + const char *backend_url, + const struct ANASTASIS_CRYPTO_AccountPublicKeyP *anastasis_pub, + ANASTASIS_PolicyLookupCallback cb, + void *cb_cls, + unsigned int version); + + +/** + * Cancel a GET /policy request. + * + * @param plo cancel the policy lookup operation + */ +void +ANASTASIS_policy_lookup_cancel ( + struct ANASTASIS_PolicyLookupOperation *plo); + + +/** + * Handle for a POST /policy operation. + */ +struct ANASTASIS_PolicyStoreOperation; + + +/** + * High-level ways how an upload may conclude. + */ +enum ANASTASIS_UploadStatus +{ + /** + * Backup was successfully made. + */ + ANASTASIS_US_SUCCESS = 0, + + /** + * Account expired or payment was explicitly requested + * by the client. + */ + ANASTASIS_US_PAYMENT_REQUIRED, + + /** + * HTTP interaction failed, see HTTP status. + */ + ANASTASIS_US_HTTP_ERROR, + + /** + * We had an internal error (not sure this can happen, + * but reserved for HTTP 400 status codes). + */ + ANASTASIS_US_CLIENT_ERROR, + + /** + * Server had an internal error. + */ + ANASTASIS_US_SERVER_ERROR, + + /** + * Truth already exists. Not applicable for policy uploads. + */ + ANASTASIS_US_CONFLICTING_TRUTH +}; + + +/** + * Result of an upload. + */ +struct ANASTASIS_UploadDetails +{ + /** + * High level status of the upload operation. Determines @e details. + */ + enum ANASTASIS_UploadStatus us; + + /** + * HTTP status code. + */ + unsigned int http_status; + + /** + * Taler error code. + */ + enum TALER_ErrorCode ec; + + union + { + + struct + { + /** + * Hash of the stored recovery data, returned if + * @e us is #ANASTASIS_US_SUCCESS. + */ + const struct GNUNET_HashCode *curr_backup_hash; + + /** + * At what time is the provider set to forget this + * policy (because the account expires)? + */ + struct GNUNET_TIME_Absolute policy_expiration; + + /** + * Version number of the resulting policy. + */ + unsigned long long policy_version; + + } success; + + /** + * Details about required payment. + */ + struct + { + /** + * A taler://pay/-URI with a request to pay the annual fee for + * the service. Returned if @e us is #ANASTASIS_US_PAYMENT_REQUIRED. + */ + const char *payment_request; + + /** + * The payment secret (aka order ID) extracted from the @e payment_request. + */ + struct ANASTASIS_PaymentSecretP ps; + } payment; + + } details; +}; + + +/** + * Callback to process a POST /policy request + * + * @param cls closure + * @param http_status HTTP status code for this request + * @param obj the decoded response body + */ +typedef void +(*ANASTASIS_PolicyStoreCallback) (void *cls, + const struct ANASTASIS_UploadDetails *up); + + +/** + * Store policies, does a POST /policy/$ACCOUNT_PUB + * + * @param ctx the CURL context used to connect to the backend + * @param backend_url backend's base URL, including final "/" + * @param anastasis_priv private key of the user's account + * @param recovery_data policy data to be stored + * @param recovery_data_size number of bytes in @a recovery_data + * @param payment_years_requested for how many years would the client like the service to store the truth? + * @param paid_order_id payment identifier of last payment + * @param payment_timeout how long to wait for the payment, use + * #GNUNET_TIME_UNIT_ZERO to let the server pick + * @param cb callback processing the response from /policy + * @param cb_cls closure for cb + * @return handle for the operation + */ +struct ANASTASIS_PolicyStoreOperation * +ANASTASIS_policy_store ( + struct GNUNET_CURL_Context *ctx, + const char *backend_url, + const struct ANASTASIS_CRYPTO_AccountPrivateKeyP *anastasis_priv, + const void *recovery_data, + size_t recovery_data_size, + uint32_t payment_years_requested, + const struct ANASTASIS_PaymentSecretP *payment_secret, + struct GNUNET_TIME_Relative payment_timeout, + ANASTASIS_PolicyStoreCallback cb, + void *cb_cls); + + +/** + * Cancel a POST /policy request. + * + * @param pso the policy store operation to cancel + */ +void +ANASTASIS_policy_store_cancel ( + struct ANASTASIS_PolicyStoreOperation *pso); + + +/****** TRUTH API ******/ + + +/** + * Operational status. + */ +enum ANASTASIS_KeyShareDownloadStatus +{ + /** + * We got the encrypted key share. + */ + ANASTASIS_KSD_SUCCESS = 0, + + /** + * Payment is needed to proceed with the recovery. + */ + ANASTASIS_KSD_PAYMENT_REQUIRED, + + /** + * The provided answer was wrong or missing. Instructions for + * getting a good answer may be provided. + */ + ANASTASIS_KSD_INVALID_ANSWER, + + /** + * To answer the challenge, the client should be redirected to + * the given URL. + */ + ANASTASIS_KSD_REDIRECT_FOR_AUTHENTICATION, + + /** + * The provider had an error. + */ + ANASTASIS_KSD_SERVER_ERROR, + + /** + * The provider claims we made an error. + */ + ANASTASIS_KSD_CLIENT_FAILURE, + + /** + * The provider does not know this truth. + */ + ANASTASIS_KSD_TRUTH_UNKNOWN, + + /** + * Too many attempts to solve the challenge were made in a short + * time. Try again laster. + */ + ANASTASIS_KSD_RATE_LIMIT_EXCEEDED + +}; + + +/** + * Detailed results from the successful download. + */ +struct ANASTASIS_KeyShareDownloadDetails +{ + + /** + * Operational status. + */ + enum ANASTASIS_KeyShareDownloadStatus status; + + /** + * Anastasis URL that returned the @e status. + */ + const char *server_url; + + /** + * Details depending on @e status. + */ + union + { + + /** + * The encrypted key share (if @e status is #ANASTASIS_KSD_SUCCESS). + */ + struct ANASTASIS_CRYPTO_EncryptedKeyShareP eks; + + /** + * Response if the challenge still needs to be answered, and the + * instructions are provided inline (no redirection). + */ + struct + { + + /** + * HTTP status returned by the server. #MHD_HTTP_ALREADY_REPORTED + * if the server did already send the challenge to the user, + * #MHD_HTTP_FORBIDDEN if the answer was wrong (or missing). + */ + unsigned int http_status; + + /** + * Response with server-side reply containing instructions for the user + */ + const char *body; + + /** + * Content-type: mime type of @e body, NULL if server did not provide any. + */ + const char *content_type; + + /** + * Number of bytes in @e body. + */ + size_t body_size; + + } open_challenge; + + /** + * URL with instructions for the user to satisfy the challenge, if + * @e status is #ANASTASIS_KSD_REDIRECT_FOR_AUTHENTICATION. + */ + const char *redirect_url; + + /** + * Response with instructions for how to pay, if + * @e status is #ANASTASIS_KSD_PAYMENT_REQUIRED. + */ + struct + { + + /** + * "taler://pay" URL with details how to pay for the challenge. + */ + const char *taler_pay_uri; + + /** + * The order ID from @e taler_pay_uri. + */ + struct ANASTASIS_PaymentSecretP payment_secret; + + } payment_required; + + + /** + * Response with details about a server-side failure, if + * @e status is #ANASTASIS_KSD_SERVER_FAILURE, + * #ANASTASIS_KSD_CLIENT_FAILURE or #ANASTASIS_KSD_TRUTH_UNKNOWN. + */ + struct + { + + /** + * HTTP status returned by the server. + */ + unsigned int http_status; + + /** + * Taler-specific error code. + */ + enum TALER_ErrorCode ec; + + } server_failure; + + } details; +}; + + +/** + * Handle for a GET /truth operation. + */ +struct ANASTASIS_KeyShareLookupOperation; + + +/** + * Callback to process a GET /truth request + * + * @param cls closure + * @param http_status HTTP status code for this request + * @param kdd details about the key share + */ +typedef void +(*ANASTASIS_KeyShareLookupCallback) ( + void *cls, + const struct ANASTASIS_KeyShareDownloadDetails *kdd); + + +/** + * Does a GET /truth. + * + * @param ctx execution context + * @param backend_url base URL of the merchant backend + * @param truth_public_key identification of the Truth + * @param truth_key Key used to Decrypt the Truth on the Server + * @param payment_secret secret from the previously done payment NULL to trigger payment + * @param payment_timeout how long to wait for the payment, use + * #GNUNET_TIME_UNIT_ZERO to let the server pick + * @param hashed_answer hashed answer to the challenge + * @param cb callback which will work the response gotten from the backend + * @param cb_cls closure to pass to the callback + * @return handle for this operation, NULL upon errors + */ +struct ANASTASIS_KeyShareLookupOperation * +ANASTASIS_keyshare_lookup ( + struct GNUNET_CURL_Context *ctx, + const char *backend_url, + const struct ANASTASIS_CRYPTO_TruthUUIDP *truth_uuid, + const struct ANASTASIS_CRYPTO_TruthKeyP *truth_key, + const struct ANASTASIS_PaymentSecretP *payment_secret, + struct GNUNET_TIME_Relative timeout, + const struct GNUNET_HashCode *hashed_answer, + ANASTASIS_KeyShareLookupCallback cb, + void *cb_cls); + + +/** + * Cancel a GET /truth request. + * + * @param tlo cancel the truth lookup operation + */ +void +ANASTASIS_keyshare_lookup_cancel ( + struct ANASTASIS_KeyShareLookupOperation *kslo); + + +/** + * Handle for a POST /truth operation. + */ +struct ANASTASIS_TruthStoreOperation; + + +/** + * Callback to process a POST /truth request + * + * @param cls closure + * @param obj the response body + */ +typedef void +(*ANASTASIS_TruthStoreCallback) (void *cls, + const struct ANASTASIS_UploadDetails *up); + + +/** + * Store Truth, does a POST /truth/$UUID + * + * @param ctx the CURL context used to connect to the backend + * @param backend_url backend's base URL, including final "/" + * @param uuid unique identfication of the Truth Upload + * @param prev_truth_data_hash hash of the previous truth upload, NULL for the first upload ever + * @param type type of the authorization method + * @param encrypted_keyshare key material to return to the client upon authorization + * @param truth_mime mime type of @e encrypted_truth (after decryption) + * @param encrypted_truth_size number of bytes in @e encrypted_truth + * @param encrypted_truth contains the @a type-specific authorization data + * @param payment_years_requested for how many years would the client like the service to store the truth? + * @param payment_timeout how long to wait for the payment, use + * #GNUNET_TIME_UNIT_ZERO to let the server pick + * @param cb callback processing the response from /truth + * @param cb_cls closure for cb + * @return handle for the operation + */ +struct ANASTASIS_TruthStoreOperation * +ANASTASIS_truth_store ( + struct GNUNET_CURL_Context *ctx, + const char *backend_url, + const struct ANASTASIS_CRYPTO_TruthUUIDP *uuid, + const char *type, + const struct ANASTASIS_CRYPTO_EncryptedKeyShareP *encrypted_keyshare, + const char *truth_mime, + size_t encrypted_truth_size, + const void *encrypted_truth, + uint32_t payment_years_requested, + struct GNUNET_TIME_Relative payment_timeout, + ANASTASIS_TruthStoreCallback cb, + void *cb_cls); + + +/** + * Cancel a POST /truth request. + * + * @param tso the truth store operation + */ +void +ANASTASIS_truth_store_cancel ( + struct ANASTASIS_TruthStoreOperation *tso); + + +#endif /* _ANASTASIS_SERVICE_H */ diff --git a/src/include/anastasis_testing_lib.h b/src/include/anastasis_testing_lib.h new file mode 100644 index 0000000..a54e3ae --- /dev/null +++ b/src/include/anastasis_testing_lib.h @@ -0,0 +1,884 @@ +/* + This file is part of Anastasis + Copyright (C) 2020 Taler Systems SA + + Anastasis is free software; you can redistribute it and/or modify it under the + terms of the GNU Lesser General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/> +*/ +/** + * @file include/anastasis_testing_lib.h + * @brief API for writing an interpreter to test Taler components + * @author Christian Grothoff <christian@grothoff.org> + * @author Dennis Neufeld + * @author Dominik Meister + */ +#ifndef ANASTASIS_TESTING_LIB_H +#define ANASTASIS_TESTING_LIB_H + +#include "anastasis.h" +#include <taler/taler_testing_lib.h> +#include <microhttpd.h> + +/* ********************* Helper functions ********************* */ + +#define ANASTASIS_FAIL() \ + do {GNUNET_break (0); return NULL; } while (0) + +/** + * Index used in #ANASTASIS_TESTING_get_trait_hash() for the current hash. + */ +#define ANASTASIS_TESTING_TRAIT_HASH_CURRENT 0 + +/** + * Index used in #SYNC_TESTING_get_trait_hash() for the previous hash. + */ +#define ANASTASIS_TESTING_TRAIT_HASH_PREVIOUS 1 + +/** + * Obtain a hash from @a cmd. + * + * @param cmd command to extract the number from. + * @param index the number's index number, #ANASTASIS_TESTING_TRAIT_HASH_CURRENT or + * #SYNC_TESTING_TRAIT_HASH_PREVIOUS + * @param[out] h set to the hash coming from @a cmd. + * @return #GNUNET_OK on success. + */ +int +ANASTASIS_TESTING_get_trait_hash (const struct TALER_TESTING_Command *cmd, + unsigned int index, + const struct GNUNET_HashCode **h); + + +/** + * Offer a hash. + * + * @param index the number's index number. + * @param h the hash to offer. + * @return #GNUNET_OK on success. + */ +struct TALER_TESTING_Trait +ANASTASIS_TESTING_make_trait_hash (unsigned int index, + const struct GNUNET_HashCode *h); + + +/** + * Obtain a truth decryption key from @a cmd. + * + * @param cmd command to extract the public key from. + * @param index usually 0 + * @param[out] key set to the account public key used in @a cmd. + * @return #GNUNET_OK on success. + */ +int +ANASTASIS_TESTING_get_trait_truth_key ( + const struct TALER_TESTING_Command *cmd, + unsigned int index, + const struct ANASTASIS_CRYPTO_TruthKeyP **key); + + +/** + * Offer an truth decryption key. + * + * @param index usually zero + * @param h the account_pub to offer. + * @return #GNUNET_OK on success. + */ +struct TALER_TESTING_Trait +ANASTASIS_TESTING_make_trait_truth_key ( + unsigned int index, + const struct ANASTASIS_CRYPTO_TruthKeyP *h); + + +/** + * Obtain an account public key from @a cmd. + * + * @param cmd command to extract the public key from. + * @param index usually 0 + * @param[out] pub set to the account public key used in @a cmd. + * @return #GNUNET_OK on success. + */ +int +ANASTASIS_TESTING_get_trait_account_pub ( + const struct + TALER_TESTING_Command *cmd, + unsigned int index, + const struct ANASTASIS_CRYPTO_AccountPublicKeyP **pub); + + +/** + * Offer an account public key. + * + * @param index usually zero + * @param h the account_pub to offer. + * @return #GNUNET_OK on success. + */ +struct TALER_TESTING_Trait +ANASTASIS_TESTING_make_trait_account_pub ( + unsigned int index, + const struct ANASTASIS_CRYPTO_AccountPublicKeyP *h); + + +/** + * Obtain an account private key from @a cmd. + * + * @param cmd command to extract the number from. + * @param index must be 0 + * @param[out] priv set to the account private key used in @a cmd. + * @return #GNUNET_OK on success. + */ +int +ANASTASIS_TESTING_get_trait_account_priv ( + const struct + TALER_TESTING_Command *cmd, + unsigned int index, + const struct ANASTASIS_CRYPTO_AccountPrivateKeyP **priv); + + +/** + * Offer an account private key. + * + * @param index usually zero + * @param priv the account_priv to offer. + * @return #GNUNET_OK on success. + */ +struct TALER_TESTING_Trait +ANASTASIS_TESTING_make_trait_account_priv ( + unsigned int index, + const struct + ANASTASIS_CRYPTO_AccountPrivateKeyP *priv); + +/** + * Obtain an account public key from @a cmd. + * + * @param cmd command to extract the payment identifier from. + * @param index the payment identifier's index number. + * @param[out] payment_secret set to the payment secret coming from @a cmd. + * @return #GNUNET_OK on success. + */ +int +ANASTASIS_TESTING_get_trait_payment_secret ( + const struct TALER_TESTING_Command *cmd, + unsigned int index, + const struct ANASTASIS_PaymentSecretP **payment_secret); + + +/** + * Offer a payment secret. + * + * @param index usually zero + * @param h the payment secret to offer. + * @return #GNUNET_OK on success. + */ +struct TALER_TESTING_Trait +ANASTASIS_TESTING_make_trait_payment_secret ( + unsigned int index, + const struct ANASTASIS_PaymentSecretP *h); + + +/** + * Obtain an truth UUID from @a cmd. + * + * @param cmd command to extract the number from. + * @param index the number's index number. + * @param[out] uuid set to the number coming from @a cmd. + * @return #GNUNET_OK on success. + */ +int +ANASTASIS_TESTING_get_trait_truth_uuid ( + const struct TALER_TESTING_Command *cmd, + unsigned int index, + const struct ANASTASIS_CRYPTO_TruthUUIDP **uuid); + + +/** + * Offer a truth UUID. + * + * @param index the number's index number. + * @param uuid the UUID to offer. + * @return #GNUNET_OK on success. + */ +struct TALER_TESTING_Trait +ANASTASIS_TESTING_make_trait_truth_uuid ( + unsigned int index, + const struct ANASTASIS_CRYPTO_TruthUUIDP *uuid); + + +/** + * Obtain an encrypted key share from @a cmd. + * + * @param cmd command to extract the number from. + * @param index the number's index number. + * @param[out] uuid set to the number coming from @a cmd. + * @return #GNUNET_OK on success. + */ +int +ANASTASIS_TESTING_get_trait_eks ( + const struct TALER_TESTING_Command *cmd, + unsigned int index, + const struct ANASTASIS_CRYPTO_EncryptedKeyShareP **eks); + + +/** + * Offer an encrypted key share. + * + * @param index the number's index number. + * @param eks the encrypted key share to offer. + * @return #GNUNET_OK on success. + */ +struct TALER_TESTING_Trait +ANASTASIS_TESTING_make_trait_eks ( + unsigned int index, + const struct ANASTASIS_CRYPTO_EncryptedKeyShareP *eks); + + +/** + * Obtain a code from @a cmd. + * + * @param cmd command to extract the number from. + * @param index the number's index number. + * @param[out] code set to the number coming from @a cmd. + * @return #GNUNET_OK on success. + */ +int +ANASTASIS_TESTING_get_trait_code ( + const struct TALER_TESTING_Command *cmd, + unsigned int index, + const char **code); + + +/** + * Offer a filename. + * + * @param index the number's index number. + * @param tpk the public key to offer. + * @return #GNUNET_OK on success. + */ +struct TALER_TESTING_Trait +ANASTASIS_TESTING_make_trait_code (unsigned int index, + const char *code); + + +/** + * Prepare the merchant execution. Create tables and check if + * the port is available. + * + * @param config_filename configuration filename. + * + * @return the base url, or NULL upon errors. Must be freed + * by the caller. + */ +char * +TALER_TESTING_prepare_merchant (const char *config_filename); + + +/** + * Start the merchant backend process. Assume the port + * is available and the database is clean. Use the "prepare + * merchant" function to do such tasks. + * + * @param config_filename configuration filename. + * + * @return the process, or NULL if the process could not + * be started. + */ +struct GNUNET_OS_Process * +TALER_TESTING_run_merchant (const char *config_filename, + const char *merchant_url); + + +/** + * Start the anastasis backend process. Assume the port + * is available and the database is clean. Use the "prepare + * anastasis" function to do such tasks. + * + * @param config_filename configuration filename. + * + * @return the process, or NULL if the process could not + * be started. + */ +struct GNUNET_OS_Process * +ANASTASIS_TESTING_run_anastasis (const char *config_filename, + const char *anastasis_url); + + +/** + * Prepare the anastasis execution. Create tables and check if + * the port is available. + * + * @param config_filename configuration filename. + * + * @return the base url, or NULL upon errors. Must be freed + * by the caller. + */ +char * +ANASTASIS_TESTING_prepare_anastasis (const char *config_filename); + + +/* ************** Specific interpreter commands ************ */ + + +/** + * Types of options for performing the upload. Used as a bitmask. + */ +enum ANASTASIS_TESTING_PolicyStoreOption +{ + /** + * Do everything by the book. + */ + ANASTASIS_TESTING_PSO_NONE = 0, + + /** + * Use random hash for previous upload instead of correct + * previous hash. + */ + ANASTASIS_TESTING_PSO_PREV_HASH_WRONG = 1, + + /** + * Request payment. + */ + ANASTASIS_TESTING_PSO_REQUEST_PAYMENT = 2, + + /** + * Reference payment order ID from linked previous upload. + */ + ANASTASIS_TESTING_PSO_REFERENCE_ORDER_ID = 4 + +}; + + +/** + * Make a "policy store" command. + * + * @param label command label + * @param anastasis_url base URL of the anastasis serving + * the policy store request. + * @param prev_upload reference to a previous upload we are + * supposed to update, NULL for none + * @param http_status expected HTTP status. + * @param pso policy store options + * @param recovery_data recovery data to post + * @param recovery_data_size size of recovery/policy data + * @return the command + */ +struct TALER_TESTING_Command +ANASTASIS_TESTING_cmd_policy_store ( + const char *label, + const char *anastasis_url, + const char *prev_upload, + unsigned int http_status, + enum ANASTASIS_TESTING_PolicyStoreOption pso, + const void *recovery_data, + size_t recovery_data_size); + + +/** + * Make the "policy lookup" command. + * + * @param label command label + * @param ANASTASIS_url base URL of the ANASTASIS serving + * the policy lookup request. + * @param http_status expected HTTP status. + * @param upload_ref reference to upload command + * @return the command + */ +struct TALER_TESTING_Command +ANASTASIS_TESTING_cmd_policy_lookup (const char *label, + const char *ANASTASIS_url, + unsigned int http_status, + const char *upload_ref); + + +/** + * Types of options for performing the upload. Used as a bitmask. + */ +enum ANASTASIS_TESTING_TruthStoreOption +{ + /** + * Do everything by the book. + */ + ANASTASIS_TESTING_TSO_NONE = 0, + + /** + * Re-use UUID of previous upload instead of creating a random one. + */ + ANASTASIS_TESTING_TSO_REFERENCE_UUID = 1, + + /** + * Explicitly request payment. + */ + ANASTASIS_TESTING_TSO_REQUEST_PAYMENT = 2, + + /** + * Reference payment order ID from linked previous upload. + */ + ANASTASIS_TESTING_TSO_REFERENCE_ORDER_ID = 4 + +}; + + +/** + * Make the "truth store" command. + * + * @param label command label + * @param anastasis_url base URL of the anastasis serving + * the truth store request. + * @param prev_upload reference to a previous upload to get a payment ID from + * @param method what authentication method is being used + * @param mime_type MIME type of @a truth_data + * @param truth_data_size number of bytes in @a truth_data + * @param truth_data recovery data to post /truth (in plaintext) + * @param tso flags + * @param http_status expected HTTP status. + * @return the command + */ +struct TALER_TESTING_Command +ANASTASIS_TESTING_cmd_truth_store (const char *label, + const char *anastasis_url, + const char *prev_upload, + const char *method, + const char *mime_type, + size_t truth_data_size, + const void *truth_data, + enum ANASTASIS_TESTING_TruthStoreOption tso, + unsigned int http_status); + + +/** + * Make the "truth store" command for a secure question. + * + * @param label command label + * @param anastasis_url base URL of the anastasis serving + * the truth store request. + * @param prev_upload reference to a previous upload to get a payment ID from + * @param answer the answer to the question + * @param tso flags + * @param http_status expected HTTP status. + * @return the command + */ +struct TALER_TESTING_Command +ANASTASIS_TESTING_cmd_truth_question ( + const char *label, + const char *anastasis_url, + const char *prev_upload, + const char *answer, + enum ANASTASIS_TESTING_TruthStoreOption tso, + unsigned int http_status); + + +/** + * Make the "keyshare lookup" command. + * + * @param label command label + * @param anastasis_url base URL of the ANASTASIS serving + * the keyshare lookup request. + * @param answer (response to challenge) + * @param payment_ref reference to the payment request + * @param upload_ref reference to upload command + * @param ksdd expected status + * @return the command + */ +struct TALER_TESTING_Command +ANASTASIS_TESTING_cmd_keyshare_lookup ( + const char *label, + const char *anastasis_url, + const char *answer, + const char *payment_ref, + const char *upload_ref, + int lookup_mode, + enum ANASTASIS_KeyShareDownloadStatus ksdd); + + +/** + * Obtain a salt from @a cmd. + * + * @param cmd command to extract the salt from. + * @param index the salt's index number. + * @param[out] s set to the salt coming from @a cmd. + * @return #GNUNET_OK on success. + */ +int +ANASTASIS_TESTING_get_trait_salt ( + const struct TALER_TESTING_Command *cmd, + unsigned int index, + const struct ANASTASIS_CRYPTO_ProviderSaltP **s); + + +/** + * Offer an salt. + * + * @param index the salt's index number. + * @param u the salt to offer. + * @return #GNUNET_OK on success. + */ +struct TALER_TESTING_Trait +ANASTASIS_TESTING_make_trait_salt ( + unsigned int index, + const struct ANASTASIS_CRYPTO_ProviderSaltP *s); + + +/** + * Make the "/config" command. + * + * @param label command label + * @param anastasis_url base URL of the ANASTASIS serving + * the /config request. + * @param http_status expected HTTP status. + * @return the command + */ +struct TALER_TESTING_Command +ANASTASIS_TESTING_cmd_config (const char *label, + const char *anastasis_url, + unsigned int http_status); + +/* ********************* test truth upload ********************* */ + +/** + * Obtain a truth from @a cmd. + * + * @param cmd command to extract the truth from. + * @param index the index of the truth + * @param[out] t set to the truth coming from @a cmd. + * @return #GNUNET_OK on success. + */ +int +ANASTASIS_TESTING_get_trait_truth (const struct TALER_TESTING_Command *cmd, + unsigned int index, + const struct ANASTASIS_Truth **t); + + +/** + * Offer a truth. + * + * @param index the truth's index number. + * @param t the truth to offer. + * @return #GNUNET_OK on success. + */ +struct TALER_TESTING_Trait +ANASTASIS_TESTING_make_trait_truth (unsigned int index, + const struct ANASTASIS_Truth *t); + +/** + * Creates a sample of id_data. + * + * @param id_data some sample data (e.g. AHV, name, surname, ...) + * @return truth in json format + */ +json_t * +ANASTASIS_TESTING_make_id_data_example (const char *id_data); + + +/** + * Make the "truth upload" command. + * + * @param label command label + * @param anastasis_url base URL of the anastasis serving our requests. + * @param id_data ID data to generate user identifier + * @param method specifies escrow method + * @param instructions specifies what the client/user has to do + * @param mime_type mime type of truth_data + * @param truth_data some truth data (e.g. hash of answer to a secret question) + * @param truth_data_size size of truth_data + * @param http_status expected HTTP status + * @param tso truth upload options + * @param upload_ref reference to the previous upload + * @return the command + */ +struct TALER_TESTING_Command +ANASTASIS_TESTING_cmd_truth_upload ( + const char *label, + const char *anastasis_url, + const json_t *id_data, + const char *method, + const char *instructions, + const char *mime_type, + const void *truth_data, + size_t truth_data_size, + unsigned int http_status, + enum ANASTASIS_TESTING_TruthStoreOption tso, + const char *upload_ref); + + +/** + * Make the "truth upload" command for a security question. + * + * @param label command label + * @param anastasis_url base URL of the anastasis serving our requests. + * @param id_data ID data to generate user identifier + * @param instructions specifies what the client/user has to do + * @param mime_type mime type of truth_data + * @param answer the answer to the security question + * @param http_status expected HTTP status + * @param tso truth upload options + * @param upload_ref reference to the previous upload + * @return the command + */ +struct TALER_TESTING_Command +ANASTASIS_TESTING_cmd_truth_upload_question ( + const char *label, + const char *anastasis_url, + const json_t *id_data, + const char *instructions, + const char *mime_type, + const void *answer, + unsigned int http_status, + enum ANASTASIS_TESTING_TruthStoreOption tso, + const char *salt_ref); + +/* ********************* test policy create ********************* */ + +/** + * Obtain a policy from @a cmd. + * + * @param cmd command to extract the policy from. + * @param index the index of the policy + * @param[out] p set to the policy coming from @a cmd. + * @return #GNUNET_OK on success. + */ +int +ANASTASIS_TESTING_get_trait_policy (const struct TALER_TESTING_Command *cmd, + unsigned int index, + const struct ANASTASIS_Policy **p); + + +/** + * Offer a policy. + * + * @param index the policy's index number. + * @param t the policy to offer. + * @return #GNUNET_OK on success. + */ +struct TALER_TESTING_Trait +ANASTASIS_TESTING_make_trait_policy (unsigned int index, + const struct ANASTASIS_Policy *p); + + +/** + * Make the "policy create" command. + * + * @param label command label + * @param ... NULL-terminated list of truth upload commands + * @return the command + */ +struct TALER_TESTING_Command +ANASTASIS_TESTING_cmd_policy_create (const char *label, + ...); + + +/* ********************* test secret share ********************* */ + +/** + * Obtain the core secret from @a cmd. + * + * @param cmd command to extract the core secret from. + * @param index the index of the core secret (usually 0) + * @param[out] s set to the core secret coming from @a cmd. + * @return #GNUNET_OK on success. + */ +int +ANASTASIS_TESTING_get_trait_core_secret (const struct + TALER_TESTING_Command *cmd, + unsigned int index, + const void **s); + + +/** + * Offer the core secret. + * + * @param index the core secret's index number (usually 0). + * @param s the core secret to offer. + * @return #GNUNET_OK on success. + */ +struct TALER_TESTING_Trait +ANASTASIS_TESTING_make_trait_core_secret (unsigned int index, + const void *s); + +/** + * Types of options for performing the secret sharing. Used as a bitmask. + */ +enum ANASTASIS_TESTING_SecretShareOption +{ + /** + * Do everything by the book. + */ + ANASTASIS_TESTING_SSO_NONE = 0, + + /** + * Request payment. + */ + ANASTASIS_TESTING_SSO_REQUEST_PAYMENT = 2, + + /** + * Reference payment order ID from linked previous upload. + */ + ANASTASIS_TESTING_SSO_REFERENCE_ORDER_ID = 4 + +}; + +/** + * Make the "secret share" command. + * + * @param label command label + * @param anastasis_url base URL of the anastasis serving our requests. + * @param config_ref reference to /config operation for @a anastasis_url + * @param prev_secret_share reference to a previous secret share command + * @param id_data ID data to generate user identifier + * @param core_secret core secret to backup/recover + * @param core_secret_size size of @a core_secret + * @param http_status expected HTTP status. + * @param sso secret share options + * @param ... NULL-terminated list of policy create commands + * @return the command + */ +struct TALER_TESTING_Command +ANASTASIS_TESTING_cmd_secret_share ( + const char *label, + const char *anastasis_url, + const char *config_ref, + const char *prev_secret_share, + const json_t *id_data, + const void *core_secret, + size_t core_secret_size, + unsigned int http_status, + enum ANASTASIS_TESTING_SecretShareOption sso, + ...); + + +/* ********************* test recover secret ********************* */ + +/** + * Types of options for performing the secret recovery. Used as a bitmask. + */ +enum ANASTASIS_TESTING_RecoverSecretOption +{ + /** + * Do everything by the book. + */ + ANASTASIS_TESTING_RSO_NONE = 0, + + /** + * Request payment. + */ + ANASTASIS_TESTING_RSO_REQUEST_PAYMENT = 2, + + /** + * Reference payment order ID from linked previous download. + */ + ANASTASIS_TESTING_RSO_REFERENCE_ORDER_ID = 4 + +}; + + +/** + * Make the "recover secret" command. + * + * @param label command label + * @param anastasis_url base URL of the anastasis serving our requests. + * @param id_data identfication data from the user + * @param version of the recovery document to download + * @param rso recover secret options + * @param download_ref salt download reference + * @return the command + */ +struct TALER_TESTING_Command +ANASTASIS_TESTING_cmd_recover_secret ( + const char *label, + const char *anastasis_url, + const json_t *id_data, + unsigned int version, + enum ANASTASIS_TESTING_RecoverSecretOption rso, + const char *download_ref, + const char *core_secret_ref); + + +/** + * Make "recover secret finish" command. + * + * @param label command label + * @param recover_label label of a "recover secret" command to wait for + * @param timeout how long to wait at most + * @return the command + */ +struct TALER_TESTING_Command +ANASTASIS_TESTING_cmd_recover_secret_finish ( + const char *label, + const char *recover_label, + struct GNUNET_TIME_Relative timeout); + + +/* ********************* test challenge answer ********************* */ +/** + * Obtain a challenge from @a cmd. + * + * @param cmd command to extract the challenge from. + * @param index the index of the challenge + * @param[out] c set to the challenge coming from @a cmd. + * @return #GNUNET_OK on success. + */ +int +ANASTASIS_TESTING_get_trait_challenge (const struct TALER_TESTING_Command *cmd, + unsigned int index, + const struct ANASTASIS_Challenge **c); + +/** + * Offer a challenge. + * + * @param index the challenge index number. + * @param c the challenge to offer. + * @return #GNUNET_OK on success. + */ +struct TALER_TESTING_Trait +ANASTASIS_TESTING_make_trait_challenge (unsigned int index, + const struct ANASTASIS_Challenge *r); + + +/** + * Create a "challenge start" command. Suitable for the "file" + * authorization plugin. + * + * @param label command label + * @param payment_ref reference to payment made for this challenge + * @param challenge_ref reference to the recovery process + * @param challenge_index defines the index of the trait to solve + * @param expected_cs expected reply type + * @return the command + */ +struct TALER_TESTING_Command +ANASTASIS_TESTING_cmd_challenge_start ( + const char *label, + const char *payment_ref, + const char *challenge_ref, + unsigned int challenge_index, + enum ANASTASIS_ChallengeStatus expected_cs); + + +/** + * Make the "challenge answer" command. + * + * @param label command label + * @param payment_ref reference to payment made for this challenge + * @param challenge_ref reference to the recovery process + * @param challenge_index defines the index of the trait to solve + * @param answer to the challenge + * @param expected_cs expected reply type + * @return the command + */ +struct TALER_TESTING_Command +ANASTASIS_TESTING_cmd_challenge_answer ( + const char *label, + const char *payment_ref, + const char *challenge_ref, + unsigned int challenge_index, + const char *answer, + unsigned int mode, + enum ANASTASIS_ChallengeStatus expected_cs); + + +#endif diff --git a/src/include/anastasis_util_lib.h b/src/include/anastasis_util_lib.h new file mode 100644 index 0000000..9515c20 --- /dev/null +++ b/src/include/anastasis_util_lib.h @@ -0,0 +1,82 @@ +/* + This file is part of Anastasis + Copyright (C) 2020 Taler Systems SA + + Anastasis is free software; you can redistribute it and/or modify it under the + terms of the GNU Lesser General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/> +*/ +/** + * @file include/anastasis_util_lib.h + * @brief anastasis client api + * @author Christian Grothoff + * @author Dominik Meister + * @author Dennis Neufeld + */ +#ifndef ANASTASIS_UTIL_LIB_H +#define ANASTASIS_UTIL_LIB_H + +#include "anastasis_error_codes.h" +#define GNU_TALER_ERROR_CODES_H 1 +#include <gnunet/gnunet_util_lib.h> +#include <taler/taler_util.h> + + +/** + * Return default project data used by Anastasis. + */ +const struct GNUNET_OS_ProjectData * +ANASTASIS_project_data_default (void); + + +/** + * Handle for the child management + */ +struct ANASTASIS_ChildWaitHandle; + +/** + * Defines a ANASTASIS_ChildCompletedCallback which is sent back + * upon death or completion of a child process. Used to trigger + * authentication commands. + * + * @param cls handle for the callback + * @param type type of the process + * @param exit_code status code of the process + * +*/ +typedef void +(*ANASTASIS_ChildCompletedCallback)(void *cls, + enum GNUNET_OS_ProcessStatusType type, + long unsigned int exit_code); + + +/** + * Starts the handling of the child processes. + * Function checks the status of the child process and sends back a + * ANASTASIS_ChildCompletedCallback upon completion/death of the child. + * + * @param proc child process which is monitored + * @param cb reference to the callback which is called after completion + * @param cb_cls closure for the callback + * @return ANASTASIS_ChildWaitHandle is returned + */ +struct ANASTASIS_ChildWaitHandle * +ANASTASIS_wait_child (struct GNUNET_OS_Process *proc, + ANASTASIS_ChildCompletedCallback cb, + void *cb_cls); + +/** + * Stop waiting on this child. + */ +void +ANASTASIS_wait_child_cancel (struct ANASTASIS_ChildWaitHandle *cwh); + + +#endif diff --git a/src/include/gettext.h b/src/include/gettext.h new file mode 100644 index 0000000..4585126 --- /dev/null +++ b/src/include/gettext.h @@ -0,0 +1,71 @@ +/* Convenience header for conditional use of GNU <libintl.h>. + Copyright Copyright (C) 1995-1998, 2000-2002 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published + by the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + USA. */ + +#ifndef _LIBGETTEXT_H +#define _LIBGETTEXT_H 1 + +/* NLS can be disabled through the configure --disable-nls option. */ +#if ENABLE_NLS + +/* Get declarations of GNU message catalog functions. */ +#include <libintl.h> + +#else + +/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which + chokes if dcgettext is defined as a macro. So include it now, to make + later inclusions of <locale.h> a NOP. We don't include <libintl.h> + as well because people using "gettext.h" will not include <libintl.h>, + and also including <libintl.h> would fail on SunOS 4, whereas <locale.h> + is GNUNET_OK. */ +#if defined(__sun) +#include <locale.h> +#endif + +/* Disabled NLS. + The casts to 'const char *' serve the purpose of producing warnings + for invalid uses of the value returned from these functions. + On pre-ANSI systems without 'const', the config.h file is supposed to + contain "#define const". */ +#define gettext(Msgid) ((const char *) (Msgid)) +#define dgettext(Domainname, Msgid) ((const char *) (Msgid)) +#define dcgettext(Domainname, Msgid, Category) ((const char *) (Msgid)) +#define ngettext(Msgid1, Msgid2, N) \ + ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) +#define dngettext(Domainname, Msgid1, Msgid2, N) \ + ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) +#define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ + ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) +/* slight modification here to avoid warnings: generate GNUNET_NO code, + not even the cast... */ +#define textdomain(Domainname) +#define bindtextdomain(Domainname, Dirname) +#define bind_textdomain_codeset(Domainname, Codeset) ((const char *) (Codeset)) + +#endif + +/* A pseudo function call that serves as a marker for the automated + extraction of messages, but does not call gettext(). The run-time + translation is done at a different place in the code. + The argument, String, should be a literal string. Concatenated strings + and other string expressions won't work. + The macro's expansion is not parenthesized, so that it is suitable as + initializer for static 'char[]' or 'const char[]' variables. */ +#define gettext_noop(String) String + +#endif /* _LIBGETTEXT_H */ diff --git a/src/include/platform.h b/src/include/platform.h new file mode 100644 index 0000000..04a2dce --- /dev/null +++ b/src/include/platform.h @@ -0,0 +1,60 @@ +/* + This file is part of TALER + Copyright (C) 2014, 2015, 2016 GNUnet e.V. and INRIA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> +*/ + +/** + * @file include/platform.h + * @brief This file contains the includes and definitions which are used by the + * rest of the modules + * @author Sree Harsha Totakura <sreeharsha@totakura.in> + */ + +#ifndef PLATFORM_H_ +#define PLATFORM_H_ + +/* Include our configuration header */ +#ifndef HAVE_USED_CONFIG_H +# define HAVE_USED_CONFIG_H +# ifdef HAVE_CONFIG_H +# include "anastasis_config.h" +# endif +#endif + + +#if (GNUNET_EXTRA_LOGGING >= 1) +#define VERBOSE(cmd) cmd +#else +#define VERBOSE(cmd) do { break; } while (0) +#endif + +/* Include the features available for GNU source */ +#define _GNU_SOURCE + +/* Include GNUnet's platform file */ +#include <gnunet/platform.h> + +/* Do not use shortcuts for gcrypt mpi */ +#define GCRYPT_NO_MPI_MACROS 1 + +/* Do not use deprecated functions from gcrypt */ +#define GCRYPT_NO_DEPRECATED 1 + +/* Ignore MHD deprecations for now as we want to be compatible + to "ancient" MHD releases. */ +#define MHD_NO_DEPRECATION 1 + +#endif /* PLATFORM_H_ */ + +/* end of platform.h */ |