/*
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 */