anastasis

Credential backup and recovery protocol and service
Log | Files | Refs | Submodules | README | LICENSE

anastasis_meta.c (4592B)


      1 /*
      2   This file is part of Anastasis
      3   Copyright (C) 2022 Anastasis SARL
      4 
      5   Anastasis is free software; you can redistribute it and/or modify it under the
      6   terms of the GNU General Public License as published by the Free Software
      7   Foundation; either version 3, or (at your option) any later version.
      8 
      9   Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
     10   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     11   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
     12 
     13   You should have received a copy of the GNU General Public License along with
     14   Anastasis; see the file COPYING.GPL.  If not, see <http://www.gnu.org/licenses/>
     15 */
     16 /**
     17  * @brief anastasis client api to get recovery document meta data
     18  * @author Christian Grothoff
     19  */
     20 #include "platform.h"
     21 #include "anastasis.h"
     22 #include <taler/taler_json_lib.h>
     23 #include <gnunet/gnunet_util_lib.h>
     24 #include <taler/taler_merchant_service.h>
     25 #include <microhttpd.h>
     26 
     27 /**
     28  * Handle for a version check operation.
     29  */
     30 struct ANASTASIS_VersionCheck
     31 {
     32   /**
     33    * Function to call with results.
     34    */
     35   ANASTASIS_MetaPolicyCallback mpc;
     36 
     37   /**
     38    * Closure for @e mpc.
     39    */
     40   void *mpc_cls;
     41 
     42   /**
     43    * Handle for the actual REST operation.
     44    */
     45   struct ANASTASIS_PolicyMetaLookupOperation *plm;
     46 
     47   /**
     48    * User identifier (needed to decrypt).
     49    */
     50   struct ANASTASIS_CRYPTO_UserIdentifierP id;
     51 };
     52 
     53 
     54 /**
     55  * Function called with results from a GET /policy/$POL/meta request
     56  *
     57  * @param cls closure with the `struct ANASTASIS_VersionCheck *`
     58  * @param dd the response details
     59  */
     60 static void
     61 meta_cb (
     62   void *cls,
     63   const struct ANASTASIS_MetaDownloadDetails *dd)
     64 {
     65   struct ANASTASIS_VersionCheck *vc = cls;
     66 
     67   vc->plm = NULL;
     68   if (MHD_HTTP_OK != dd->http_status)
     69   {
     70     vc->mpc (vc->mpc_cls,
     71              0,
     72              GNUNET_TIME_UNIT_ZERO_TS,
     73              NULL,
     74              NULL);
     75     ANASTASIS_recovery_get_versions_cancel (vc);
     76     return;
     77   }
     78   for (size_t i = 0; i<dd->details.ok.metas_length; i++)
     79   {
     80     const struct ANASTASIS_MetaDataEntry *meta
     81       = &dd->details.ok.metas[i];
     82     const char *secret_name = NULL;
     83     const struct GNUNET_HashCode *eph;
     84     void *dec;
     85     size_t dec_len;
     86 
     87     if (GNUNET_OK !=
     88         ANASTASIS_CRYPTO_recovery_metadata_decrypt (
     89           &vc->id,
     90           meta->meta_data,
     91           meta->meta_data_size,
     92           &dec,
     93           &dec_len))
     94     {
     95       GNUNET_break_op (0);
     96       continue;
     97     }
     98     if (sizeof (*eph) > dec_len)
     99     {
    100       GNUNET_break_op (0);
    101       GNUNET_free (dec);
    102       continue;
    103     }
    104     eph = dec;
    105     if (sizeof (*eph) < dec_len)
    106     {
    107       secret_name = (const char *) &eph[1];
    108       dec_len -= sizeof (*eph);
    109       if ('\0' != secret_name[dec_len - 1])
    110       {
    111         GNUNET_break_op (0);
    112         GNUNET_free (dec);
    113         continue;
    114       }
    115     }
    116     vc->mpc (vc->mpc_cls,
    117              meta->version,
    118              meta->server_time,
    119              eph,
    120              secret_name);
    121     GNUNET_free (dec);
    122   }
    123   vc->mpc (vc->mpc_cls,
    124            0,
    125            GNUNET_TIME_UNIT_ZERO_TS,
    126            NULL,
    127            NULL);
    128   ANASTASIS_recovery_get_versions_cancel (vc);
    129 }
    130 
    131 
    132 struct ANASTASIS_VersionCheck *
    133 ANASTASIS_recovery_get_versions (
    134   struct GNUNET_CURL_Context *ctx,
    135   const json_t *id_data,
    136   unsigned int max_version,
    137   const char *anastasis_provider_url,
    138   const struct ANASTASIS_CRYPTO_ProviderSaltP *provider_salt,
    139   ANASTASIS_MetaPolicyCallback mpc,
    140   void *mpc_cls)
    141 {
    142   struct ANASTASIS_VersionCheck *vc;
    143   struct ANASTASIS_CRYPTO_AccountPublicKeyP account_pub;
    144 
    145   vc = GNUNET_new (struct ANASTASIS_VersionCheck);
    146   vc->mpc = mpc;
    147   vc->mpc_cls = mpc_cls;
    148   ANASTASIS_CRYPTO_user_identifier_derive (id_data,
    149                                            provider_salt,
    150                                            &vc->id);
    151   ANASTASIS_CRYPTO_account_public_key_derive (&vc->id,
    152                                               &account_pub);
    153   vc->plm = ANASTASIS_policy_meta_lookup (ctx,
    154                                           anastasis_provider_url,
    155                                           &account_pub,
    156                                           max_version,
    157                                           &meta_cb,
    158                                           vc);
    159   if (NULL == vc->plm)
    160   {
    161     GNUNET_break (0);
    162     GNUNET_free (vc);
    163     return NULL;
    164   }
    165   return vc;
    166 }
    167 
    168 
    169 void
    170 ANASTASIS_recovery_get_versions_cancel (struct ANASTASIS_VersionCheck *vc)
    171 {
    172   if (NULL != vc->plm)
    173   {
    174     ANASTASIS_policy_meta_lookup_cancel (vc->plm);
    175     vc->plm = NULL;
    176   }
    177   GNUNET_free (vc);
    178 }