/* This file is part of Anastasis Copyright (C) 2019-2022 Anastasis SARL Anastasis is free software; you can redistribute it and/or modify it under the terms of the GNU 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.LIB. If not, see */ /** * @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 #include /** * 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 { /** * HTTP status returned. */ unsigned int http_status; /** * Taler-specific error code, #TALER_EC_NONE on success. */ enum TALER_ErrorCode ec; /** * Full response in JSON, if provided. */ const json_t *response; /** * Details depending on @e http_status. */ union { /** * Details on #MHD_HTTP_OK. */ struct { /** * Protocol version supported by the server. */ const char *version; /** * Business name of the anastasis provider. */ const char *business_name; /** * 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; /** * Provider salt. */ struct ANASTASIS_CRYPTO_ProviderSaltP provider_salt; } ok; } details; }; /** * 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 acfg configuration obtained, NULL if we could not parse it */ typedef void (*ANASTASIS_ConfigCallback)(void *cls, 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 meta data result. */ struct ANASTASIS_MetaDataEntry { /** * Timestamp of the backup at the server. */ struct GNUNET_TIME_Timestamp server_time; /** * The encrypted meta data we downloaded. */ const void *meta_data; /** * Number of bytes in @e meta_data. */ size_t meta_data_size; /** * Policy version this @e meta_data is for. */ uint32_t version; }; /** * Detailed results for meta data download. */ struct ANASTASIS_MetaDownloadDetails { /** * HTTP status returned. */ unsigned int http_status; /** * Taler-specific error code, #TALER_EC_NONE on success. */ enum TALER_ErrorCode ec; /** * Full response in JSON, if provided. */ const json_t *response; /** * Details depending on @e http_status. */ union { /** * Details on #MHD_HTTP_OK. */ struct { /** * Version-sorted array of meta data we downloaded. */ const struct ANASTASIS_MetaDataEntry *metas; /** * Number of entries in @e metas. */ size_t metas_length; } ok; } details; }; /** * Callback to process a GET /policy/$POL/meta request * * @param cls closure * @param dd the response details */ typedef void (*ANASTASIS_PolicyMetaLookupCallback) ( void *cls, const struct ANASTASIS_MetaDownloadDetails *dd); /** * Does a GET /policy/$POL/meta. * * @param ctx execution context * @param backend_url base URL of the merchant backend * @param anastasis_pub public key of the user's account * @param max_version maximum version number to fetch * @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_PolicyMetaLookupOperation * ANASTASIS_policy_meta_lookup ( struct GNUNET_CURL_Context *ctx, const char *backend_url, const struct ANASTASIS_CRYPTO_AccountPublicKeyP *anastasis_pub, uint32_t max_version, ANASTASIS_PolicyMetaLookupCallback cb, void *cb_cls); /** * Cancel a GET /policy/$POL/meta request. * * @param plo cancel the policy lookup operation */ void ANASTASIS_policy_meta_lookup_cancel ( struct ANASTASIS_PolicyMetaLookupOperation *plo); /** * Detailed results from the successful download. */ struct ANASTASIS_DownloadDetails { /** * HTTP status returned. */ unsigned int http_status; /** * Taler-specific error code, #TALER_EC_NONE on success. */ enum TALER_ErrorCode ec; /** * Details depending on @e http_status. */ union { /** * Details on #MHD_HTTP_OK. */ struct { /** * 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; } ok; } details; }; /** * Handle for a GET /policy operation. */ struct ANASTASIS_PolicyLookupOperation; /** * Callback to process a GET /policy request * * @param cls closure * @param dd the response details */ typedef void (*ANASTASIS_PolicyLookupCallback) (void *cls, 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_Timestamp 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 up 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 recovery_meta_data policy meta data to be stored * @param recovery_meta_data_size number of bytes in @a recovery_meta_data * @param payment_years_requested for how many years would the client like the service to store the truth? * @param payment_secret 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 @a 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, const void *recovery_meta_data, size_t recovery_meta_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 ******/ /** * 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 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); /** * Possible ways how to proceed with a challenge. */ enum ANASTASIS_ChallengeDetailType { /** * A challenge TAN was written to a file. * The name of the file is provided. */ ANASTASIS_CS_FILE_WRITTEN, /** * A challenge TAN was sent to the customer. * A hint may be provided as to the address used. */ ANASTASIS_CS_TAN_SENT, /** * A challenge TAN was already recently sent to the customer. * A hint may be provided as to the address used. */ ANASTASIS_CS_TAN_ALREADY_SENT, /** * The customer should wire funds to the bank * account address provided. */ ANASTASIS_CS_WIRE_FUNDS }; /** * This structure contains information about where to wire the funds * to authenticate as well as a hint as to which bank account to send * the funds from. */ struct ANASTASIS_WireFundsDetails { /** * Answer code expected. */ uint64_t answer_code; /** * How much should be sent. */ struct TALER_Amount amount; /** * IBAN where to send the funds. */ const char *target_iban; /** * Name of the business receiving the funds. */ const char *target_business_name; /** * Wire transfer subject to use. */ const char *wire_transfer_subject; }; /** * Information returned for a POST /truth/$TID/challenge request. */ struct ANASTASIS_TruthChallengeDetails { /** * HTTP status returned by the server. */ unsigned int http_status; /** * Taler-specific error code, #TALER_EC_NONE on success. */ enum TALER_ErrorCode ec; /** * Full response in JSON, if provided. */ const json_t *response; /** * Details depending on @e http_status. */ union { /** * Information for @e http_status of #MHD_HTTP_OK. */ struct { /** * Meta-state about how the challenge was * initiated and what is to be done next. */ enum ANASTASIS_ChallengeDetailType cs; /** * Details depending on @e cs. */ union { /** * If @e cs is #ANASTASIS_CS_FILE_WRITTEN, this * is the filename with the challenge code. */ const char *challenge_filename; /** * If @e cs is #ANASTASIS_CS_TAN_SENT, this * is human-readable information as to where * the TAN was sent. */ const char *tan_address_hint; /** * If @e cs is #ANASTASIS_CS_WIRE_FUNDS, this * structure contains information about where * to wire the funds to authenticate as well * as a hint as to which bank account to send * the funds from. */ struct ANASTASIS_WireFundsDetails wire_funds; } details; } success; /** * Information returne if @e http_status is #MHD_HTTP_PAYMENT_REQUIRED */ 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; /** * Data extracted from the payto:// URI. */ const struct TALER_MERCHANT_PayUriData *pd; } payment_required; } details; }; /** * Handle for a POST /truth/$TID/challenge operation. */ struct ANASTASIS_TruthChallengeOperation; /** * Callback to process a POST /truth/$TID/challenge response. * * @param cls closure * @param tcd details about the key share */ typedef void (*ANASTASIS_TruthChallengeCallback) ( void *cls, const struct ANASTASIS_TruthChallengeDetails *tcd); /** * Makes a POST /truth/$TID/challenge request. * * @param ctx execution context * @param backend_url base URL of the merchant backend * @param truth_uuid 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 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_TruthChallengeOperation * ANASTASIS_truth_challenge ( 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, ANASTASIS_TruthChallengeCallback cb, void *cb_cls); /** * Cancel a POST /truth/$TID/challenge request. * * @param[in] tco operation to cancel */ void ANASTASIS_truth_challenge_cancel ( struct ANASTASIS_TruthChallengeOperation *tco); /** * Information returned for a POST /truth/$TID/solve request. */ struct ANASTASIS_TruthSolveReply { /** * HTTP status returned by the server. */ unsigned int http_status; /** * Taler-specific error code, #TALER_EC_NONE on success. */ enum TALER_ErrorCode ec; /** * Details depending on @e http_status. */ union { /** * Information returned if @e http_status is #MHD_HTTP_OK. */ struct { /** * The encrypted key share. */ struct ANASTASIS_CRYPTO_EncryptedKeyShareP eks; } success; /** * Information returne if @e http_status is #MHD_HTTP_PAYMENT_REQUIRED */ 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; /** * Data extracted from the payto:// URI. */ const struct TALER_MERCHANT_PayUriData *pd; } payment_required; /** * Information returne if @e http_status is #MHD_HTTP_TOO_MANY_REQUESTS. */ struct { /** * How many requests are allowed at most per @e request_frequency? */ uint32_t request_limit; /** * Frequency at which requests are allowed / new challenges are * created. */ struct GNUNET_TIME_Relative request_frequency; } too_many_requests; } details; }; /** * Handle for a POST /truth/$TID/solve operation. */ struct ANASTASIS_TruthSolveOperation; /** * Callback to process a POST /truth/$TID/solve response. * * @param cls closure * @param kdd details about the key share */ typedef void (*ANASTASIS_TruthSolveCallback) ( void *cls, const struct ANASTASIS_TruthSolveReply *trs); /** * Makes a POST /truth/$TID/solve request. * * @param ctx execution context * @param backend_url base URL of the merchant backend * @param truth_uuid 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 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_TruthSolveOperation * ANASTASIS_truth_solve ( 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_TruthSolveCallback cb, void *cb_cls); /** * Cancel a POST /truth/$TID/solve request. * * @param[in] tso handle of the operation to cancel */ void ANASTASIS_truth_solve_cancel ( struct ANASTASIS_TruthSolveOperation *tso); #endif /* _ANASTASIS_SERVICE_H */