diff options
Diffstat (limited to 'src/lib/anastasis_meta.c')
-rw-r--r-- | src/lib/anastasis_meta.c | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/src/lib/anastasis_meta.c b/src/lib/anastasis_meta.c new file mode 100644 index 0000000..ae20db5 --- /dev/null +++ b/src/lib/anastasis_meta.c @@ -0,0 +1,178 @@ +/* + This file is part of Anastasis + Copyright (C) 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.GPL. If not, see <http://www.gnu.org/licenses/> +*/ +/** + * @brief anastasis client api to get recovery document meta data + * @author Christian Grothoff + */ +#include "platform.h" +#include "anastasis.h" +#include <taler/taler_json_lib.h> +#include <gnunet/gnunet_util_lib.h> +#include <taler/taler_merchant_service.h> + + +/** + * Handle for a version check operation. + */ +struct ANASTASIS_VersionCheck +{ + /** + * Function to call with results. + */ + ANASTASIS_MetaPolicyCallback mpc; + + /** + * Closure for @e mpc. + */ + void *mpc_cls; + + /** + * Handle for the actual REST operation. + */ + struct ANASTASIS_PolicyMetaLookupOperation *plm; + + /** + * User identifier (needed to decrypt). + */ + struct ANASTASIS_CRYPTO_UserIdentifierP id; +}; + + +/** + * Function called with results from a GET /policy/$POL/meta request + * + * @param cls closure with the `struct ANASTASIS_VersionCheck *` + * @param dd the response details + */ +static void +meta_cb ( + void *cls, + const struct ANASTASIS_MetaDownloadDetails *dd) +{ + struct ANASTASIS_VersionCheck *vc = cls; + + vc->plm = NULL; + if (MHD_HTTP_OK != dd->http_status) + { + vc->mpc (vc->mpc_cls, + 0, + GNUNET_TIME_UNIT_ZERO_TS, + NULL, + NULL); + ANASTASIS_recovery_get_versions_cancel (vc); + return; + } + for (size_t i = 0; i<dd->details.ok.metas_length; i++) + { + const struct ANASTASIS_MetaDataEntry *meta + = &dd->details.ok.metas[i]; + const char *secret_name = NULL; + const struct GNUNET_HashCode *eph; + void *dec; + size_t dec_len; + + if (GNUNET_OK != + ANASTASIS_CRYPTO_recovery_metadata_decrypt ( + &vc->id, + meta->meta_data, + meta->meta_data_size, + &dec, + &dec_len)) + { + GNUNET_break_op (0); + continue; + } + if (sizeof (*eph) > dec_len) + { + GNUNET_break_op (0); + GNUNET_free (dec); + continue; + } + eph = dec; + if (sizeof (*eph) < dec_len) + { + secret_name = (const char *) &eph[1]; + dec_len -= sizeof (*eph); + if ('\0' != secret_name[dec_len - 1]) + { + GNUNET_break_op (0); + GNUNET_free (dec); + continue; + } + } + vc->mpc (vc->mpc_cls, + meta->version, + meta->server_time, + eph, + secret_name); + GNUNET_free (dec); + } + vc->mpc (vc->mpc_cls, + 0, + GNUNET_TIME_UNIT_ZERO_TS, + NULL, + NULL); + ANASTASIS_recovery_get_versions_cancel (vc); +} + + +struct ANASTASIS_VersionCheck * +ANASTASIS_recovery_get_versions ( + struct GNUNET_CURL_Context *ctx, + const json_t *id_data, + unsigned int max_version, + const char *anastasis_provider_url, + const struct ANASTASIS_CRYPTO_ProviderSaltP *provider_salt, + ANASTASIS_MetaPolicyCallback mpc, + void *mpc_cls) +{ + struct ANASTASIS_VersionCheck *vc; + struct ANASTASIS_CRYPTO_AccountPublicKeyP account_pub; + + vc = GNUNET_new (struct ANASTASIS_VersionCheck); + vc->mpc = mpc; + vc->mpc_cls = mpc_cls; + ANASTASIS_CRYPTO_user_identifier_derive (id_data, + provider_salt, + &vc->id); + ANASTASIS_CRYPTO_account_public_key_derive (&vc->id, + &account_pub); + vc->plm = ANASTASIS_policy_meta_lookup (ctx, + anastasis_provider_url, + &account_pub, + max_version, + &meta_cb, + vc); + if (NULL == vc->plm) + { + GNUNET_break (0); + GNUNET_free (vc); + return NULL; + } + return vc; +} + + +void +ANASTASIS_recovery_get_versions_cancel (struct ANASTASIS_VersionCheck *vc) +{ + if (NULL != vc->plm) + { + ANASTASIS_policy_meta_lookup_cancel (vc->plm); + vc->plm = NULL; + } + GNUNET_free (vc); +} |