/* 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 */ /** * @brief anastasis client api to get recovery document meta data * @author Christian Grothoff */ #include "platform.h" #include "anastasis.h" #include #include #include /** * 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; idetails.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); }